Angular2, evaluate template from string inside a component

前端 未结 3 759
佛祖请我去吃肉
佛祖请我去吃肉 2020-12-01 13:32

It\'s possible evaluate template from string in a variable?. I need place the string in the component instead of the expression, e.g.

template: \"

3条回答
  •  粉色の甜心
    2020-12-01 13:51

    You can create your own directive that will do it:

    compile.directive.ts

    @Directive({
      selector: '[compile]'
    })
    export class CompileDirective implements OnChanges {
      @Input() compile: string;
      @Input() compileContext: any;
    
      compRef: ComponentRef;
    
      constructor(private vcRef: ViewContainerRef, private compiler: Compiler) {}
    
      ngOnChanges() {
        if(!this.compile) {
          if(this.compRef) {
            this.updateProperties();
            return;
          }
          throw Error('You forgot to provide template');
        }
    
        this.vcRef.clear();
        this.compRef = null;
    
        const component = this.createDynamicComponent(this.compile);
        const module = this.createDynamicModule(component);
        this.compiler.compileModuleAndAllComponentsAsync(module)
          .then((moduleWithFactories: ModuleWithComponentFactories) => {
            let compFactory = moduleWithFactories.componentFactories.find(x => x.componentType === component);
    
            this.compRef = this.vcRef.createComponent(compFactory);
            this.updateProperties();
          })
          .catch(error => {
            console.log(error);
          });
      }
    
      updateProperties() {
        for(var prop in this.compileContext) {
          this.compRef.instance[prop] = this.compileContext[prop];
        }
      }
    
      private createDynamicComponent (template:string) {
        @Component({
          selector: 'custom-dynamic-component',
          template: template,
        })
        class CustomDynamicComponent {}
        return CustomDynamicComponent;
      }
    
      private createDynamicModule (component: Type) {
        @NgModule({
          // You might need other modules, providers, etc...
          // Note that whatever components you want to be able
          // to render dynamically must be known to this module
          imports: [CommonModule],
          declarations: [component]
        })
        class DynamicModule {}
        return DynamicModule;
      }
    }
    

    Usage:

    @Component({
      selector: 'product-item',
      template: `
        
    `, }) export class ProductItemComponent { @Input() name: string; @Input() price: number = 0; @Input() template: string = `{{ name }} {{ price | currency }}`; }

    Plunker Example

    See also

    • Angular 2.1.0 create child component on the fly, dynamically

提交回复
热议问题