Angular 使用(单击)函数2动态显示包含HTML的元素

Angular 使用(单击)函数2动态显示包含HTML的元素,angular,typescript2.0,Angular,Typescript2.0,我有一个递归树结构,其中包含每个节点都具有“htmlStringContent”属性的节点。当我使用嵌套的“节点”组件显示树并尝试显示我使用的html内容时: <div [innerHtml]="node.htmlStringContent"></div> Edit3:基本上,这个问题是问在angular 2/ionic 2中是否尽可能从对象的属性显示HTML,同时保留(单击)功能。我也愿意接受解决方法的答案。CFR演示: @组件({ 选择器:“我的应用程序”, 模板:

我有一个递归树结构,其中包含每个节点都具有“htmlStringContent”属性的节点。当我使用嵌套的“节点”组件显示树并尝试显示我使用的html内容时:

<div [innerHtml]="node.htmlStringContent"></div>
Edit3:基本上,这个问题是问在angular 2/ionic 2中是否尽可能从对象的属性显示HTML,同时保留(单击)功能。我也愿意接受解决方法的答案。

CFR演示:

@组件({
选择器:“我的应用程序”,
模板:`
添加HTML(动态使用CRF)
Angular2应用组件

这里是动态html `, }) 导出类应用程序{ 名称:字符串; @ViewChild('subcainer1',{read:ViewContainerRef})subcainer1:ViewContainerRef; 建造师( 专用compFactoryResolver:ComponentFactoryResolver ) { this.name='Angular2' } addComponents(){ let compFactory:组件工厂; compFactory=此.compFactoryResolver.resolveComponentFactory(Part1组件); 此.subcainer1.createComponent(compFactory); } }
如果我理解正确,您需要使用动态模板并在运行时编译它们。如果是,则需要使用角度编译器:

@Component({
    selector: 'my-app',
    template: `
      <h1>Angular 2 Dynamic Component</h1>
      <template #container></template>
    `
})
export class AppComponent implements AfterContentInit, OnDestroy {
  private dynamicComponentRefs: ComponentRef[] = [];

  @ViewChild('container', { read: ViewContainerRef }) container: ViewContainerRef;

  constructor(private resolver: ComponentFactoryResolver,
              private compiler: Compiler) {}

  ngAfterContentInit() {
    let html = `
      <div>Always Visible</div>
      <div [hidden]="clause1">Hidden because of clause1 = true</div>
      <div [hidden]="clause2">Visible because of clause2 = false</div>
      <button type="button" (click)="buttonClicked()">Click me!</button>
      <div *ngIf="clicked">You clicked the button!</div>
    `;

    this.compiler.compileModuleAndAllComponentsAsync(createDynamicComponent(html))
        .then((mwcf: ModuleWithComponentFactories) => {
          let factory: ComponentFactory = mwcf.componentFactories.find(cf => 
            cf.componentType.name === 'DynamicComponent');
            this.dynamicComponentRefs
              .push(this.container.createComponent(factory));
        });
  }

  ngOnDestroy() {
    /* Make sure you destroy all dynamically created components to avoid leaks */
    this.dynamicComponentRefs.forEach(dcr => {
      dcr.destroy();
    });
  }

}

export function createDynamicComponent(html: string): Type<NgModule> {
  @Component({
    template: html,
  })
  class DynamicComponent {
    private clause1: boolean = true;
    private clause2: boolean = false;
    private clicked = false;

    buttonClicked() {
      this.clicked = true;
    }
  }

  @NgModule({
    imports: [CommonModule],
    declarations: [DynamicComponent],
  })
  class DynamicComponentModule {}

  return DynamicComponentModule;
}
@组件({
选择器:“我的应用程序”,
模板:`
角2动态分量
`
})
导出类AppComponent实现AfterContentInit、OnDestroy{
私有dynamicComponentRefs:ComponentRef[]=[];
@ViewChild('container',{read:ViewContainerRef})container:ViewContainerRef;
构造函数(专用解析器:ComponentFactoryResolver,
专用编译器:编译器){}
ngAfterContentInit(){
让html=`
始终可见
因为第1条而隐藏=真
由于第2条可见=错误
点击我!
你点击了按钮!
`;
this.compiler.compileModuleAndAllComponentsAsync(createDynamicComponent(html))
.然后((mwcf:ModuleWithComponentFactorys)=>{
让工厂:ComponentFactory=mwcf.ComponentFactorys.find(cf=>
cf.componentType.name===“DynamicComponent”);
此.dynamicComponentRefs
.push(this.container.createComponent(工厂));
});
}
恩贡德斯特罗(){
/*确保销毁所有动态创建的组件以避免泄漏*/
this.dynamicComponentRefs.forEach(dcr=>{
dcr.destroy();
});
}
}
导出函数createDynamicComponent(html:string):类型{
@组成部分({
模板:html,
})
类DynamicComponent{
私有子句1:布尔值=真;
私有子句2:布尔值=false;
private=false;
按钮点击(){
this.clicked=true;
}
}
@NGD模块({
导入:[CommonModule],
声明:[DynamicComponent],
})
类DynamicComponentModule{}
返回动态组件模块;
}
基本上,您需要动态创建一个组件和声明它的模块(例如,通过函数),并将模板作为参数传递给它。然后可以在模块上调用
compileemoduleandallcomponentsasync()
,并获取所需的组件工厂。然后通过
ViewContainerRef.createComponent()
方法在DOM中呈现它

这里是工作普朗克:


但是请记住,目前这种方法只能用于JIT编译。在AOT编译中,角度编译器不可用,尝试使用它将抛出错误。

这样,单击事件将不起作用。您有一个创建组件,然后您将能够生成一个链接中已显示的单击事件。@micronyks,但我仍然必须使用[innerHtml]来显示html内容?我理解,但与angular1一样,angular2没有
$compile
服务,因此您可以使用
componentFactoryResolver
@micronyks来完成它,但不完全确定如何使用它。。你们能更详细一点吗?对于树形结构,我不确定,但当模板有角度上下文时,你们应该只使用CFR。我看到这会动态创建组件。。但是我已经有了一个嵌套的组件结构,它使用递归ngfor显示,这个解决方案如何显示组件属性中包含的html字符串并正确显示它,包括单击功能??
transform(v: string) : SafeHtml {
  return this._sanitizer.bypassSecurityTrustHtml(v); 
} 
@Component({
  selector: 'my-app',
  template: `

     <button (click)="addComponents()">Add HTML (dynamically using CRF)</button>

     <h1>Angular2 AppComponent</h1>
     <hr>

     <div>
     <h5>dynamic html goes here</h5>
      <div class="container">
        <template #subContainer1></template>
      </div>
     </div>


  `,

})
export class App {
    name:string;
    @ViewChild('subContainer1', {read: ViewContainerRef}) subContainer1: ViewContainerRef;

    constructor(
      private compFactoryResolver: ComponentFactoryResolver
      ) {
      this.name = 'Angular2'
    }

    addComponents() {

      let compFactory: ComponentFactory;

      compFactory = this.compFactoryResolver.resolveComponentFactory(Part1Component);
      this.subContainer1.createComponent(compFactory);

    }
  }
@Component({
    selector: 'my-app',
    template: `
      <h1>Angular 2 Dynamic Component</h1>
      <template #container></template>
    `
})
export class AppComponent implements AfterContentInit, OnDestroy {
  private dynamicComponentRefs: ComponentRef[] = [];

  @ViewChild('container', { read: ViewContainerRef }) container: ViewContainerRef;

  constructor(private resolver: ComponentFactoryResolver,
              private compiler: Compiler) {}

  ngAfterContentInit() {
    let html = `
      <div>Always Visible</div>
      <div [hidden]="clause1">Hidden because of clause1 = true</div>
      <div [hidden]="clause2">Visible because of clause2 = false</div>
      <button type="button" (click)="buttonClicked()">Click me!</button>
      <div *ngIf="clicked">You clicked the button!</div>
    `;

    this.compiler.compileModuleAndAllComponentsAsync(createDynamicComponent(html))
        .then((mwcf: ModuleWithComponentFactories) => {
          let factory: ComponentFactory = mwcf.componentFactories.find(cf => 
            cf.componentType.name === 'DynamicComponent');
            this.dynamicComponentRefs
              .push(this.container.createComponent(factory));
        });
  }

  ngOnDestroy() {
    /* Make sure you destroy all dynamically created components to avoid leaks */
    this.dynamicComponentRefs.forEach(dcr => {
      dcr.destroy();
    });
  }

}

export function createDynamicComponent(html: string): Type<NgModule> {
  @Component({
    template: html,
  })
  class DynamicComponent {
    private clause1: boolean = true;
    private clause2: boolean = false;
    private clicked = false;

    buttonClicked() {
      this.clicked = true;
    }
  }

  @NgModule({
    imports: [CommonModule],
    declarations: [DynamicComponent],
  })
  class DynamicComponentModule {}

  return DynamicComponentModule;
}