# Components Manual

## Create a component

Using the Angular CLI to generate a new component.

* You can use the ng generate (or just ng g) command to generate Angular components:

```bash
ng generate component my-new-component
ng g component my-new-component # using the alias
# components support relative path generation
# if you locate in the directory src/app/feature/ and you run
ng g component new-cmp
# your component will be generated in src/app/feature/new-cmp
# but if you were to run
ng g component ./newer-cmp
# your component will be generated in src/app/newer-cmp
# if in the directory src/app you can also run
ng g component feature/new-cmp
# and your component will be generated in src/app/feature/new-cmp
```

* The CLI creates a new folder `src/app/NewComponent/` and generates four files: .ts, .scss, .html and .spec.ts.
* For example if you generate a component called *Client*, the NewComponent class file is as follows:

```typescript
import { Component, OnInit } from '@angular/core';

@Component({
selector: 'wm-client',
templateUrl: './client.component.html',
styleUrls: ['./client.component.scss']
})
export class ClientComponent implements OnInit {

    constructor() { }

    ngOnInit() {
    }
}
```

* It's important to mention that all control components in WebMAP extends from ControlComponent class as follow:

```typescript
export class ClientComponent extends ControlComponent { ...
```

* Class metadata properties meanings
  1. `selector` — the component's CSS element selector
  2. `templateUrl` — the location of the component's HTML template file.
  3. `styleUrls` — the location of the component's private CSS styles.
* Add an `<wm-client>` element to the AppComponent template file to display it.
* Add its respective directives into the HTML file to complete ControlComponent inheritance as follow:

```markup
<wm-client wmControls [ngClass] ="class"></wm-client>
```

### One-way binding : \[]

Example of one-way binding:

```markup
<div>
    <label>name:
      <input [ngModel]="model.name" placeholder="name">
    </label>
</div>
```

### Two-way binding : \[()]

Example of two-way binding:

```markup
<div>
    <label>name:
      <input [(ngModel)]="model.name" placeholder="name">
    </label>
</div>
```

### Possible blueprints in the table below

| Scaffold  | Usage                           |
| --------- | ------------------------------- |
| Component | ng g component my-new-component |
| Directive | ng g directive my-new-directive |
| Pipe      | ng g pipe my-new-pipe           |
| Service   | ng g service my-new-service     |
| Class     | ng g class my-new-class         |
| Guard     | ng g guard my-new-guard         |
| Interface | ng g interface my-new-interface |
| Enum      | ng g enum my-new-enum           |
| Module    | ng g module my-module           |

## Remote Data Binding

> The **WebMap BackEnd** requires to have a WebAPI controller that responds to the component's data queries. This controller should be in charge of identifying the data that will be sent to the controller.

Some components work on single data, like a `TextBox` or a `Label`, but other components handle a collection of data, like a `ComboBox` or a `Grid`.

To handle those data collections the component requires to bind the data source to a remote service. Below are the steps required to bind remote data to the component.

1. Create a property in the `*.component.ts` file that will be used to bind the value in the `HTML`, and another property that will be used to hold the URL to query the server for data that belongs to API on assets.

   ```typescript
    export class ClientComponent implements OnInit {
        /* New property to hold data */
        items: object[] = [];

        /* New property to hold URL */
        url: string = 'api/combobox';
   ```
2. Include the `WebMapService` in the constructor, the dependency injection from Angular will be in charge of providing the service when needed.

   ```typescript
    import { WebMapService } from '/some/route/services';

    export class HeroesComponent implements OnInit {
        /* New Property to hold data */
        items: object[] = [];

        constructor(private service: WebMapService) {
        }
   ```
3. Implement the `ngOnInit` event by calling the `WebMapService` and setting the returned data to the `items` property.

   ```typescript
    export class HeroesComponent implements OnInit {
        /* New Property to hold data */
        items: object[] = [];

        ngOnInit() {
            this.service.fetch<object>(this.url, this.id).subscribe( data => {
                this.items = data;
            });
        }
   ```

## Imports

In every new component some Angular imports must be added, these imports are used for special purposes like detect changes, render styles correctly and use the Web Map 5 native services. There are three mandatory services:

* `ChangeDetectorRef` : It is used to detect model changes and refresh every model change in the component.
* `Renderer2`: It provides an easy and safe way to modify DOM elements.
* `ElementRef`: It allows the access to the component root DOM element.

The first step is import the angular classes needed:

```typescript
import { ChangeDetectorRef, ElementRef, Renderer2 } from '@angular/core';
```

\*This is an example, more imports can be included as is needed for each component.

And the second and the last one step is add the classes in the constructor and pass their definitions to the base constructor.

```typescript
constructor(private serviceRef: WebMapService, private refChange: ChangeDetectorRef,
            private render2: Renderer2, private elem: ElementRef) {
    super(serviceRef, refChange, render2, elem);
}
```


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.gapvelocity.ai/webmap/general/frontend/documentation/winforms-angular-components/setup/components-manual.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
