javascript - Angular2,从组件内的字符串评估模板

标签 javascript angular angular-template

可以从变量中的字符串评估模板吗?我需要将字符串而不是表达式放在组件中, 例如

template: "<div>{{ template_string }}</div>"

template_string 包含:<b>{{ name }}</b>

并且所有的都应该评估为<div><b>My Name</b></div>

但我看到<div>{{ template_string }}</div>

我需要像 {{ template_string | eval }} 这样的东西或其他东西来评估当前上下文中变量的内容。

这可能吗?我需要一些东西来使用这种方法,因为 template_string可以在使用组件时更改。

Edit1:

Angular 版本:4.0.3

例如

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

用法:

<product-item [name]="product.name" [price]="product.price"></product-item>

预期: 产品名称 3.00 美元

输出: {{ name }} <b>{{ price | currency }}</b>

最佳答案

您可以创建自己的指令来执行此操作:

compile.directive.ts

@Directive({
  selector: '[compile]'
})
export class CompileDirective implements OnChanges {
  @Input() compile: string;
  @Input() compileContext: any;

  compRef: ComponentRef<any>;

  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<any>) => {
        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<any>) {
    @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;
  }
}

用法:

@Component({
  selector: 'product-item',
  template: `
    <div class="product">
      <ng-container *compile="template; context: this"></ng-container>
    </div>
  `,
})
export class ProductItemComponent {
  @Input() name: string;
  @Input() price: number = 0;
  @Input() template: string = `{{ name }} <b>{{ price | currency }}</b>`;
}

Plunker Example

另见

关于javascript - Angular2,从组件内的字符串评估模板,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44077994/

相关文章:

angular - 显示 1 条数据而不是所有 ngFor - Angular 11

javascript - ng2-ckeditor 如何在编辑器未自动加载时将焦点设置到编辑器

javascript - 使用 Material 以 Angular 动态内联形式

javascript - 在 Bootstrap 4.5 中使用图标

javascript - 具有反应式表单值的 Node js 过滤器数组

javascript - 没有模板 Controller 的 Angular 指令绑定(bind)

javascript - 两条线之间的填充区域 - Chart.js v2

Angular2 ReactiveFormsControl : how to bind radio buttons?

angular - 如何在 amcharts 4 中为 LineSeries 添加 click\hit 事件?

angular - 如何将变量从 .ts 传递到 html