我正在构建一个小型引用应用程序,以了解如何在一个组件中动态注入组件以查看页面上的内容。我得到一个指向viewContainerRef对象的错误。
这个组件应该在视图中显示注入的组件的内容,但它抛出了一个错误:
以下是引发错误的StatsComponent:
export class StatsComponent implements AfterViewInit, OnDestroy {
@Input() dynComp: DynamicComponent;
@ViewChild(ComponentHostDirective) appComponentHost: ComponentHostDirective;
componentRef: ComponentRef<any>;
constructor(private componentFactoryResolver: ComponentFactoryResolver) { }
ngAfterViewInit() {
this.loadComponent();
}
ngOnDestroy() {
this.componentRef.destroy();
}
loadComponent() {
console.log('inside stats component: ', this.dynComp);
const comp = this.dynComp;
const componentFactory = this.componentFactoryResolver.resolveComponentFactory(comp.component);
console.log('host: ', this.appComponentHost); // <-- this is undefined
const viewContainerRef = this.appComponentHost.viewContainerRef;
viewContainerRef.clear();
this.componentRef = viewContainerRef.createComponent(componentFactory);
(<DynamicComponent>this.componentRef.instance).data = comp.data;
}
}
我有一个工作演示和一个项目。
为什么没有引用容器?
[更新]:现在可以了!去我的演示和github项目看看它的实际效果。
最佳答案
Angular无法识别模板中的@ViewChild(ComponentHostDirective)
,因为您没有将ComponentHostDirective
指令包含到用于编译StatsComponent
的指令列表中:
要了解Angular用来编译Angular模板的指令,请看这个答案Angular 2 Use component from another module(参见图)
我知道你已经在ComponentHostDirective
内声明了AppModule
。但是StatsComponent
是在HomeModule
中声明的,这个模块对ComponentHostDirective
一无所知。我们必须在HomeModule
中声明或导入此指令。
如果我们在ComponentHostDirective
中声明HomeModule
,就会得到错误
类型componenthostdirective是两个模块声明的一部分:
应用模块和家庭模块!SharedModule
救援:
src/app/shared/shared.module.ts文件
@NgModule({
imports: [
CommonModule
],
declarations: [
ComponentHostDirective
],
exports: [
CommonModule,
ComponentHostDirective
]
})
export class SharedModule {}
应用模块.ts
@NgModule({
declarations: [
ComponentHostDirective <== remove it
],
imports: [
...
SharedModule, // add this
...
]
})
export class AppModule { }
主页.module.ts
@NgModule({
imports: [
...
SharedModule, // add this
...
]
})
export class HomeModule { }
之后,您的
appComponentHost
属性将引用ComponentHostDirective
实例。另外,您将得到错误
expressionchangedafterithasbeencheckederror:表达式已更改
检查之后。上一个值:“未定义”。当前值:
“顾客”。
组件创建后。
不要在
ngAfterViewInit
钩子中更改绑定。改为使用ngOnInit
:export class StatsComponent implements OnInit, OnDestroy {
...
ngOnInit() {
this.loadComponent();
}
这篇文章非常详细地解释了这种行为(谢谢@maximus)。
最后你会看到结果:
Everything you need to know about the ExpressionChangedAfterItHasBeenCheckedError error