我有一个包含节点的递归树结构,每个节点都有一个'htmlStringContent'属性。当我使用嵌套的“节点”组件显示树并尝试呈现我使用的html内容时:
<div [innerHtml]="node.htmlStringContent"></div>
HTML正确显示但是对于以下元素:
<a (click)="function()">click me</a>
(单击)功能不起作用。我知道这有previously been posted但是由于最近出现了大量的更新,我无法找到任何解决方案。 This answer让我相信我应该使用ngComponentOutlet指令,但我不确定如何...
如何获得角度来绑定此点击功能?
编辑:我被告知使用ComponentFactoryResolver,但无法看到我如何使用它来正确显示html。任何人都可以提供进一步的帮助吗?
Edit2:我在[innerHtml]
上显示之前通过清理管道解析'htmlStringContent'transform(v: string) : SafeHtml {
return this._sanitizer.bypassSecurityTrustHtml(v);
}
Edit3:基本上这个问题是询问是否尽可能在角度2 /离子2中的对象上显示HTML,同时在其上保留(点击)功能。我也愿意解决问题。
答案 0 :(得分:4)
CFR DEMO:https://plnkr.co/edit/jKEaDz1JVFoAw0YfOXEU?p=preview
@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);
}
}
答案 1 :(得分:3)
如果我理解正确,您需要使用动态模板并在运行时编译它们。如果是这样,那么你需要使用角度编译器:
@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;
}
基本上你需要动态创建一个组件和声明它的模块(例如通过一个函数),并将模板作为参数传递给它。然后,您可以在模块上调用compileModuleAndAllComponentsAsync()
并获取所需的组件工厂。然后,它是通过ViewContainerRef.createComponent()
方法在DOM中呈现它的问题。
以下是工作人员:dynamic template component
请记住 - 目前 - 此方法只能用于JIT编译。在AOT编译中,角度编译器不可用,尝试使用它会引发错误。