我正在面对Angular的问题和来自 @angular/cdk
的 CdkPortal
/ CdkPortalHost
.
我创建了一个服务,允许我注册一个具有给定名称的 CdkPortalHost
,并在任何时候设置它 Component
.
该服务看起来像这样:
private portalHosts : { [location : string] : CdkPortalOutlet } = {};
private portals : { [location : string] : any} = {};
/** Sets the PortalHost for the given location. */
public register(location : string, portalHost : CdkPortalOutlet) {
this.portalHosts[location] = portalHost;
}
/** Sets the Component for the given location. */
public setComponent<T>(location : string, type : ComponentType<T>) : ComponentRef<T> {
let ref : ComponentRef<T> = null;
let portalHost = this.portalHosts[location];
if (portalHost) {
if (portalHost.hasAttached()) {
portalHost.portal.detach();
this.portals[location] = null;
}
ref = portalHost.attachComponentPortal(new ComponentPortal(type));
this.portals[location] = ref.instance;
}
return ref;
}
然后我注册了一个像这样的PortalHost:
@ViewChild(PortalHostDirective)
private portalHost : PortalHostDirective;
public ngAfterContentInit() {
this.dynamicComponentService.register("Location", this.portalHost);
}
在另一个组件中,它是注册PortalHost的Component的子组件,我将动态组件设置为:
public ngAfterContentInit() {
this.dynamicComponentService.setComponent("Location", MyDynamicComponent);
}
出于测试目的,我使用MyDynamicComponent的简单模板:
<div *ngIf="true">Test</div>
现在,当我运行App时,我收到以下错误:
Error: ExpressionChangedAfterItHasBeenCheckedError: Expression has changed after it was checked.
Previous value: 'undefined'. Current value: 'true'.
It seems like the view has been created after its parent and its children have been dirty checked.
Has it been created in a change detection hook ?
我见过几个类似的问题,但"window.setTimeout" -Workaround对我不起作用 .
我也为PortalHost-Registration和Component-Creation尝试了不同的生命周期钩子,但结果总是一样的......
我使用的是Angular 5.0.1和Material / CDK 5.0.0-rc0 .
我错过了什么或这是一个错误吗?
它与Angular/Material#5268有关吗?
1 回答
ngAfterContentInit
对于门户网站插座的更改检测生效可能为时过早 . 在注册门户网站插座并在ngOnInit
中注册组件时,我遇到了这个确切的问题:在
setTimeout
中包装最后一行时,代码按预期工作 .