How can I use/create dynamic template to compile dynamic Component with Angular 2.0?

后端 未结 15 1868
忘掉有多难
忘掉有多难 2020-11-21 05:14

I want to dynamically create a template. This should be used to build a ComponentType at runtime and place (even replace) it somewhere inside of the ho

15条回答
  •  隐瞒了意图╮
    2020-11-21 06:03

    I decided to compact everything I learned into one file. There's a lot to take in here especially compared to before RC5. Note that this source file includes the AppModule and AppComponent.

    import {
      Component, Input, ReflectiveInjector, ViewContainerRef, Compiler, NgModule, ModuleWithComponentFactories,
      OnInit, ViewChild
    } from '@angular/core';
    import {BrowserModule} from '@angular/platform-browser';
    
    @Component({
      selector: 'app-dynamic',
      template: '

    Dynamic Components


    ' }) export class DynamicComponentRenderer implements OnInit { factory: ModuleWithComponentFactories; constructor(private vcRef: ViewContainerRef, private compiler: Compiler) { } ngOnInit() { if (!this.factory) { const dynamicComponents = { sayName1: {comp: SayNameComponent, inputs: {name: 'Andrew Wiles'}}, sayAge1: {comp: SayAgeComponent, inputs: {age: 30}}, sayName2: {comp: SayNameComponent, inputs: {name: 'Richard Taylor'}}, sayAge2: {comp: SayAgeComponent, inputs: {age: 25}}}; this.compiler.compileModuleAndAllComponentsAsync(DynamicModule) .then((moduleWithComponentFactories: ModuleWithComponentFactories) => { this.factory = moduleWithComponentFactories; Object.keys(dynamicComponents).forEach(k => { this.add(dynamicComponents[k]); }) }); } } addNewName(value: string) { this.add({comp: SayNameComponent, inputs: {name: value}}) } addNewAge(value: number) { this.add({comp: SayAgeComponent, inputs: {age: value}}) } add(comp: any) { const compFactory = this.factory.componentFactories.find(x => x.componentType === comp.comp); // If we don't want to hold a reference to the component type, we can also say: const compFactory = this.factory.componentFactories.find(x => x.selector === 'my-component-selector'); const injector = ReflectiveInjector.fromResolvedProviders([], this.vcRef.parentInjector); const cmpRef = this.vcRef.createComponent(compFactory, this.vcRef.length, injector, []); Object.keys(comp.inputs).forEach(i => cmpRef.instance[i] = comp.inputs[i]); } } @Component({ selector: 'app-age', template: '
    My age is {{age}}!
    ' }) class SayAgeComponent { @Input() public age: number; }; @Component({ selector: 'app-name', template: '
    My name is {{name}}!
    ' }) class SayNameComponent { @Input() public name: string; }; @NgModule({ imports: [BrowserModule], declarations: [SayAgeComponent, SayNameComponent] }) class DynamicModule {} @Component({ selector: 'app-root', template: `

    {{message}}



    `, }) export class AppComponent { message = 'this is app component'; @ViewChild(DynamicComponentRenderer) dcr; } @NgModule({ imports: [BrowserModule], declarations: [AppComponent, DynamicComponentRenderer], bootstrap: [AppComponent] }) export class AppModule {}`

提交回复
热议问题