角度:在[innerHtml]中绑定变量

时间:2018-07-17 09:43:00

标签: angular typescript

我正在尝试使用[innerHtml]将div中的数据绑定。如何通知angular使用变量而不是原始文本。这是我的设置:

<div *ngFor="let data of someData">
    <div *ngFor="let odata of someOtherData;trackBy:id">
        <div [innerHTML]="odata.template | pipeToSanitize"></div>
    </div>
</div>

数据如下:

someOtherData = [{
                    'id': 1,
                    'template': '<div class="{{data.class}}"><md-icon>{{data.icon}}</md-icon></div>'
                }, 
                {
                    'id': 2,
                    'template': '<div>{{data.timestampStr}}</div>'
                }, 
                {
                    'id': 3,
                    'template': '<div>{{data.message}}</div>'
                }]

someData = [{
               'message': 'Message 1',
               'timestampStr': '2016/12/13 09:25:00',
               'class': 'events-warn-color',
               'icon': 'warning'
            }, 
           {
               'message': 'Message 2',
               'timestampStr': '2016/12/13 10:36:00',
               'class': 'events-warn-color',
               'icon': 'warning'
           }];

现在我正在获取{{data.icon}}等。照原样。如何用'someOtherData'对象的内容替换它。预先感谢

4 个答案:

答案 0 :(得分:2)

您必须创建编译器指令才能评估模板字符串:

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;
    }
  }

模板

<div *ngFor="let data of someData">
    <div *ngFor="let odata of someOtherData;">
          <ng-container *compile="odata.template; context:{data:data}"></ng-container>
    </div>
</div>
  

您仍然需要处理角材料模块,我并没有暗示我的在线示例,只需检查编译直接注释即可

stackblitz template compile

选中此Angular2, evaluate template from string inside a component

答案 1 :(得分:0)

为什么使用[innerHTML]

尝试

<div>{{odata.template | pipeToSanitize}}</div>

答案 2 :(得分:0)

编辑:您也可以尝试这样做吗?

<div *ngFor="let data of someData">
    <div *ngFor="let odata of getData(data);trackBy:id">
        <div [innerHTML]="odata.template | pipeToSanitize"></div>
    </div>
</div>

getDataFormated(data:any):any{
return [{
                    'id': 1,
                    'template': '<div class="{{data.class}}"><md-icon>{{data.icon}}</md-icon></div>'
                }, 
                {
                    'id': 2,
                    'template': '<div>{{data.timestampStr}}</div>'
                }, 
                {
                    'id': 3,
                    'template': '<div>{{data.message}}</div>'
                }]
}

答案 3 :(得分:0)

[innerHtml]在大多数情况下是不错的选择,但是对于非常大的字符串或在html中需要硬编码的样式时,它会失败。

您可以在下面检查答案以获得一个好主意。特别是 Piotrek的答案

Angular HTML binding