我有一个简单的组件:
@Component({
selector: '[group_id]'
})
export class ItemComponent {}
我还有一个组件,我尝试将所有传递给此组件的子ItemComponent
作为内容。
@Component({
selector : 'selector',
template : '<ng-content></ng-content>',
})
export class SelectorComponent implements AfterContentInit {
@ContentChildren(ItemComponent) items;
ngAfterContentInit() {
console.log (this.items);
}
}
现在我在应用程序的某个地方使用我的SelectorComponent
:
<selector>
<div [innerHTML]="'<p group_id>A</p>' | safeHtml"></div>
<p group_id>B</p>
<p group_id>C</p>
<p group_id>D</p>
</selector>
在ngAfterContentInit
的{{1}}钩子中只获得3个结果(B,C,D元素)。如果元素A是SelectorComponent
,我如何访问它?
是否可以跳过要求SafeValue
(XSS保护)?是否有其他方法来访问此组件(我不想访问DOM元素,但获取组件引用)。
答案 0 :(得分:1)
Angular不知道使用[innerHTML]
或在运行时动态添加的其他HTML添加的内容。
Angular在构建应用程序时,在部署之前编译模板,并忽略在运行时添加的所有HTML。
你可以强制执行
constructor(private elRef:ElementRef) {}
ngAfterContentInit() {
this.elRef.nativeElement.querySelector(...)
}
或加载动态平台以编译组件atr untime,如How can I use/create dynamic template to compile dynamic Component with Angular 2.0?
中所述答案 1 :(得分:1)
感谢@GünterZöchbauer和link他发表了一条评论和答案here我找到了解决方案:
我决定使用文档所说的ngComponentOutlet:
NgComponentOutlet为动态组件创建提供了一种声明方法
首先我做了一个动态组件:
import {Component, OnChanges, OnInit, Input, NgModule,NgModuleFactory,Compiler, SimpleChanges} from '@angular/core';
import { SharedModule } from './shared.module';
@Component({
selector: 'dynamic',
template: `<ng-container *ngComponentOutlet="dynamicComponent;ngModuleFactory: dynamicModule;"></ng-container>`
})
export class DynamicComponent {
dynamicComponent: any;
dynamicModule : NgModuleFactory<any>;
@Input('html') html: string;
constructor(private compiler: Compiler) {}
ngOnChanges(changes: SimpleChanges) {
if (changes['html'] && !changes['html'].isFirstChange()) {
this.dynamicComponent = this.createNewComponent(this.html);
this.dynamicModule = this.compiler.compileModuleSync(this.createComponentModule(this.dynamicComponent));
}
}
ngOnInit() {
this.dynamicComponent = this.createNewComponent(this.html);
this.dynamicModule = this.compiler.compileModuleSync(this.createComponentModule(this.dynamicComponent));
}
protected createComponentModule(componentType: any) {
@NgModule({
imports : [SharedModule],
declarations: [
componentType
],
entryComponents: [ componentType ]
})
class RuntimeComponentModule {
}
// a module for just this Type
return RuntimeComponentModule;
}
protected createNewComponent(template: string) {
@Component({
selector: 'dynamic-component',
template: template ? template: '<div></div>'
})
class MyDynamicComponent {}
return MyDynamicComponent;
}
}
然后我将动态组件导入我的模块:
import { DynamicComponent } from './dynamic-item/dynamic-item';
@NgModule({
declarations: [
...
DynamicComponent,
],
exports: [
...
DynamicComponent,
]
})
export class ComponentsModule { }
不,我可以将动态组件用于任何动态加载的html模板:
<dynamic [html]="dynamicHtml"></dynamic>
其中dynamicHtml
可以包含任何现有组件/指令/等的任何html:
dynamicHtml: string = "<p group_id>A</p>";
值得注意的是,这种方法需要JIT编译器,因此在开发过程中一切正常,但在使用AoT进行编译后,运行时出错:
错误错误:未加载运行时编译器
根据其中一条评论中的原始问题,@GünterZöchbauer发布了feature request的链接,可以解决该问题。目前,如果您想使用此方法,请不要使用AoT编译。