JSPM

  • Created
  • Published
  • Downloads 48
  • Score
    100M100P100Q72299F
  • License MIT

Package Exports

  • angular2-dynamic-component
  • angular2-dynamic-component/index

This package does not declare an exports field, so the exports above have been automatically detected and optimized by JSPM instead. If any package subpath is missing, it is recommended to post an issue to the original package (angular2-dynamic-component) to support the "exports" field. If that is not possible, create a JSPM override to customize the exports field for this package.

Readme

angular2-dynamic-component & angular2-dynamic-directive

An implementation of dynamic component wrapper at Angular2 [4.1.2] (AoT compatible). Also, you must see the solution out of the box before using this component: (NgComponentOutlet, since 4.0.x)

https://angular.io/docs/ts/latest/api/common/index/NgComponentOutlet-directive.html

Description

Date of creation: 18 Jun [starting with Angular 2.0.0-rc.2].

Installation

1 At first, you need to install the core-js npm module.
2 Then you need to install the ts-metadata-helper dependency package (don't worry, it's very small and simple, I like "reusable" approach)

npm install ts-metadata-helper --save

3 And after that, you have to install the target package

npm install angular2-dynamic-component --save

4 Then you must apply the DynamicComponentModule

import {DynamicComponentModule} from 'angular2-dynamic-component/index';

@NgModule({
    imports: [DynamicComponentModule]
})

Demo

1 git clone --progress -v "git@github.com:apoterenko/angular2-dynamic-component.git" "D:\sources"
2 cd D:\sources\angular2-dynamic-component\demo
3 npm install
4 npm start

Features

1 Support of dynamicComponentReady & dynamicComponentBeforeReady output events. See below.
2 Support of dynamic-component directive. See below.
3 Support of DynamicComponent component. See below.
4 Support of Dynamic within Dynamic strategy (see demo inside).
@Component(...)
export class AppComponent {
    extraTemplate = `<DynamicComponent [componentTemplate]='"<span>Dynamic inside dynamic!</span>"'></DynamicComponent>`;
    extraModules = [DynamicComponentModule];
    ...
}
<template dynamic-component
          [componentModules]="extraModules"
          [componentTemplate]='extraTemplate'></template>
5 Support of componentTemplateUrl attribute. This attribute allows getting resource via Angular2 HTTP/Ajax.

Also, 301, 302, 307, 308 HTTP statuses are supported (recursive redirection). The componentRemoteTemplateFactory (IComponentRemoteTemplateFactory) attribute allows prepare http response before rendering.

@Component(...)
export class AppComponent {
    dynamicCallback(scope) {
        console.log('Hi there! Context value is:', scope.contextValue); // Hi there! Context value is: 100500
    }
}
<template dynamic-component
          (dynamicComponentReady)="dynamicCallback($event)"
          [componentContext]="{contextValue: 100500}"
          [componentDefaultTemplate]='"<span style=\"color: red\">This is fallback template</span>"'
          [componentTemplateUrl]='"https://test-cors.appspot.com"'></template>
6 Support of componentContext attribute.

This attribute can refer to owner component (via self = this) or any other object.

@Component(...)
export class AppComponent {
    self = this;
    dynamicContextValue = 100500;
    changedValue = 0;
    dynamicExtraModules = [FormsModule];
}
<template dynamic-component
          [componentContext]="self"
          [componentModules]="dynamicExtraModules"
          [componentTemplate]='"<span [innerHTML]=\"changedValue\"></span><input type=\"text\" [(ngModel)]=\"dynamicContextValue\" (ngModelChange)=\"changedValue = $event\">"'></template>
7 Support of dynamic injected modules via the DynamicComponentModuleFactory.

The CommonModule module is imported by default.

import {DynamicComponentModuleFactory} from "angular2-dynamic-component/index";
@NgModule({
    imports: [..., 
        DynamicComponentModuleFactory.buildModule([
            FormsModule
        ])
    ],
    ...
    bootstrap: [AppComponent]
})
export class AppModule {}
<template dynamic-component
          [componentContext]="{dynamicContextValue: 100500, changedValue: 0}"
          [componentTemplate]='"<span [innerHTML]=\"changedValue\"></span><input type=\"text\" [(ngModel)]=\"dynamicContextValue\" (ngModelChange)=\"changedValue = $event\">"'></template>
8 Support of componentModules attribute.
@Component(...)
export class AppComponent {
    dynamicExtraModules = [FormsModule];
}
<template dynamic-component
          [componentModules]="dynamicExtraModules"
          [componentContext]="{dynamicContextValue: 100500, changedValue: 0}"
          [componentTemplate]='"<span [innerHTML]=\"changedValue\"></span><input type=\"text\" [(ngModel)]=\"dynamicContextValue\" (ngModelChange)=\"changedValue = $event\">"'></template>
9 Support of componentType attribute.
<template dynamic-component
          *ngFor="let field of columns"
          [componentType]="field.type"
          [componentContext]="field.context">
</template>
@Component(...)
export class AppComponent {
    columns = [{
        type: TextField,
        context: {
            fieldName: 'description',
            value: 'Test description'
        }
    }, {
        type: CheckboxField,
        context: {
            fieldName: 'expired',
            value: true
        }
    }];
    ngOnInit() {
        setTimeout(() => {
            console.log(JSON.stringify(this.columns));  // [{"context":{"fieldName":"description","value":"Next value"}},{"context":{"fieldName":"expired","value":false}}]
        }, 3000);
    }
import {
    Component,
    Input,
} from '@angular/core';

@Component({
    selector: 'DynamicTextField',       // It can be absent => selector === "TextField"
    template: `<input name="{{fieldName}}" type="text" [value]="value">`,
})
export class TextField {
    @Input() fieldName: string;
    @Input() value: string;

    constructor(
        private appState: AppState,
        private elementRef: ElementRef,
        private appRef: ApplicationRef
    ) {
        console.log('The TextField constructor has been called');
    }

    ngOnInit() {
        setTimeout(() => this.value = this.fieldName + ': next value', 4000);
        this.elementRef.nativeElement.childNodes[0].style.color = 'red';
    }
}

@Component({
    selector: 'DynamicCheckboxField',       // It can be absent => selector === "CheckboxField"
    template: `<input name="{{fieldName}}" type="checkbox" [checked]="value">`,
})
export class CheckboxField {
    @Input() fieldName: string;
    @Input() value: boolean;

    constructor() {
        console.log('The CheckboxField constructor has been called');
    }

    ngOnInit() {
        setTimeout(() => this.value = !this.value, 1000);
    }
}
10 Support of componentTemplatePath attribute. This analogue of templateUrl parameter for @Component.

License

Licensed under MIT.