Dynamic Control Support

WebMAP's offer the possibility to add new component dynamically to a container control like a panel, form, tabpage and others.

@dataTransfer Decorator

First, you need to know about the @dataTransfer decorator, this decorator is used to register the types of the controls that are going to be displayed dynamically.

The function of the @dataTransfer decorator maps the MapperId value with the corresponding component class, for example if you want to enable the LabelComponent to be displayed dynamically you need to map it with the 'lbl' MapperId value.

@Component({
  changeDetection: ChangeDetectionStrategy.OnPush,
  selector: 'wm-label',
  styleUrls: ['./label.component.scss'],
  templateUrl: './label.component.html'
})
@dataTransfer(['lbl'])
export class LabelComponent extends ControlComponent implements Label {

  constructor(private changeDetector: ChangeDetectorRef, private renderer2: Renderer2, private element: ElementRef) {
    super(changeDetector, renderer2, element);
   }

The @dataTransfer decorator takes an array of strings indicating which of the MapperIds correspond to this component. A MapperId is an unique identifier that tells the front-end framework the type of each model.

The TypeResolver class

The TypeResolver class is a small dictionary that keeps the relationship between the MapperId values and the Component classes.

export class TypeResolver {

    static typesDictionary: any = {};

    static registrateType(key: string, type: any): void {
        TypeResolver.typesDictionary[key] = type;
    }

    static getType(key: string): string {
        return TypeResolver.typesDictionary[key];
    }

}

Every time the @dataTransfer decorator is processed it registrates the types in the TypesResolver dictionary that is used for the dynamic component container component the WM-Container.

The Dynamic Controls Container

There is a component that use the TypeResolver dictionary to show the dynamic controls, this is the WM-Container.

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

The wm-container is used inside the other container components html templates like the Panel.

<fieldset [disabled]="disabled" [ngClass] ="class" wmControls>
    <ng-content></ng-content>
    <wm-container [controls]="model.Controls"></wm-container>
</fieldset>

It receives the Controls property as binding. This property contains a collection of uniqueIds and boolean values that indicates if it is added or removed from the container model.

{
    '123': true,
    '345': true,
    '678': false
};

If you want to create a new container component you only need to add the wm-container component in the component's html template and bind the Controls property.