JSPM

  • Created
  • Published
  • Downloads 46
  • Score
    100M100P100Q72567F
  • 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 (2.1.0 & AOT compatible).

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
  1. And after that, you have to install the target package
npm install angular2-dynamic-component --save

Use case #0

app.html

<template dynamic-component
          [componentModules]="extraModules"
          [componentInputData]="componentInputData"
          [componentTemplate]="componentTemplate"></template>

Use case #1

app.html

<ButtonsToolbar></ButtonsToolbar><br>
<ButtonsToolbar></ButtonsToolbar>
<template ngFor let-button [ngForOf]="buttons">
  <ButtonsToolbarPlaceholder [componentType]="button.type" [buttonName]="button.name">
  </ButtonsToolbarPlaceholder>
</template>
export interface ButtonType {
    name:string;
    type:{new ():IButton};
}

@Component({
    selector: 'ButtonsToolbar',
    template: require('./ButtonsToolbar.html')
})
export class ButtonsToolbar {

    buttons:Array<ButtonType> = [
        {
            name: 'GreenButtonName',
            type: GreenButton
        },
        {
            name: 'RedButtonName',
            type: RedButton
        }
    ];
}
import {DynamicComponent, DynamicComponentMetadata} from 'angular2-dynamic-component/index';

class ButtonsToolbarComponent extends DynamicComponentMetadata {

    constructor(public selector:string = 'ButtonsToolbarPlaceholder') {
        super();
    }
}

@Component(new ButtonsToolbarComponent())
export class ButtonsToolbarPlaceholder extends DynamicComponent implements IButton {

    @Input() buttonName:string;
    @Input() componentType:{new ():IButton};

    constructor(...) {
        super(element, viewContainer, compiler, http);
    }
}
export interface IButton {
    buttonName:string;
}

@Component({
    selector: 'GreenButton',
    template: '<span style="color: green; width: 50px; border: 1px solid black; padding: 6px; margin: 6px;">The first button with name: {{ buttonName }}</span>',
})
export class GreenButton implements IButton {

    @Input() public buttonName:string;
}

@Component({
    selector: 'RedButton',
    template: '<span style="color: red; width: 50px; border: 1px solid black; padding: 6px; margin: 6px;">The second button with name: {{ buttonName }}</span>',
})
export class RedButton implements IButton {
    @Input() public buttonName:string;
}

Preview

Use case #2. Using the "componentTemplate" attribute

app.ts

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

@NgModule({
    imports: [DynamicComponentModule]
})
...

class DynamicContext {
  value:string;

  onChange() {
    console.log(this.value)
  }
}

@Component(...)
class App {
    private componentTemplate:string = '<input type="text" [(ngModel)]="value" (ngModelChange)="onChange($event)"/>';
    private extraModules = [FormsModule];
    private context = new DynamicContext();
}

app.html

<DynamicComponent [componentTemplate]="componentTemplate" 
                  [componentInputData]="context"
                  [componentModules]="extraModules">
</DynamicComponent>

Use case #3. Using the "componentTemplateUrl" attribute

The main feature is the support of http 301 and http 302 statuses.

app.ts

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

@NgModule({
    imports: [DynamicComponentModule]
})

app.html

<DynamicComponent [componentTemplateUrl]="'http://www.yandex.ru'">
</DynamicComponent>

Use case #4. Using the "componentModules" and "componentInputData" attribute

app.ts

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

@NgModule({
    imports: [DynamicComponentModule]
})
...

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

@Component({
    ...
    template: `
    <DynamicComponent [componentModules]="extraModules"
                      [componentInputData]="inputData"
                      [componentTemplate]="template"></DynamicComponent>
  `
})
export class App {

    template: string = 'Empty current date';
    extraModules:Array<any> = [InnerModule];
    inputData: IComponentInputData = {currentDate: new Date()};

    ngOnInit() {
        setTimeout(() => {
            this.template = 'Current date is: {{ currentDate | date }}<br>Custom pipe value is: {{ "input value" | myPipe }}';
        }, 1000);
    }
}

InnerModule.ts

import {NgModule, Pipe} from '@angular/core';

@Pipe({
    name: 'myPipe',
})
class MyPipe {
    transform(value: any): string {
        return 'transformed value';
    }
}

@NgModule({
    declarations: [MyPipe],
    exports: [
        MyPipe
    ]
})
export class InnerModule {
}

Publish

npm run deploy

License

Licensed under MIT.