[英]Angular ExpressionChangedAfterItHasBeenCheckedError in dynamically created component
I am facing an Issue with Angular and the CdkPortal
/ CdkPortalHost
from @angular/cdk
. 我面临来自Angular和来自@angular/cdk
的CdkPortal
/ CdkPortalHost
的问题。
I created a service, which allowes me to register a CdkPortalHost
with a given name and set it's Component
in any moment. 我创建了一个服务,该服务使我可以使用给定名称注册CdkPortalHost
并随时将其设置为Component
。
The service looks like this: 该服务如下所示:
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;
}
Then I registered a PortalHost like this: 然后,我像这样注册了PortalHost:
@ViewChild(PortalHostDirective)
private portalHost : PortalHostDirective;
public ngAfterContentInit() {
this.dynamicComponentService.register("Location", this.portalHost);
}
In an other Component, which is a child of the Component that registers the PortalHost, I set the dynamic Component like this: 在另一个组件(该组件是注册PortalHost的组件的子组件)中,我将动态组件设置如下:
public ngAfterContentInit() {
this.dynamicComponentService.setComponent("Location", MyDynamicComponent);
}
For testing-purposes I use a simple template for the MyDynamicComponent: 出于测试目的,我为MyDynamicComponent使用了一个简单的模板:
<div *ngIf="true">Test</div>
Now, when I run the App, I get the following error: 现在,当我运行该应用程序时,出现以下错误:
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 ?
I have seen a few similar questions, but the "window.setTimeout"-Workaround did not work for me. 我已经看到了一些类似的问题,但是“ window.setTimeout”-解决方法对我不起作用。
Also I tryed differed lifecycle-hooks for the PortalHost-Registration and the Component-Creation but the result was always the same... 我也为PortalHost-Registration和Component-Creation尝试了不同的生命周期挂钩,但是结果始终相同...
I am using Angular 5.0.1 and Material/CDK 5.0.0-rc0. 我正在使用Angular 5.0.1和Material / CDK 5.0.0-rc0。
Am I missing something or is this a bug? 我是否缺少某些东西或这是一个错误?
Is it related to Angular/Material#5268 与Angular / Material#5268有关吗
ngAfterContentInit
may be too early for the change detection of the portal outlet to take effect. ngAfterContentInit
可能为时过早,门户网站出口的更改检测无法生效。 I experienced this exact isuue when registering the portal outlet and register a component to it in an ngOnInit
: 在注册门户网站出口并在ngOnInit
注册组件时,我遇到了这个确切的ngOnInit
:
this.tabPortalHost = new DomPortalOutlet(
this.tabContentOutlet.nativeElement,
this.componentFactoryResolver,
this.appRef,
this.injector
);
const portal = new ComponentPortal(this.tabs[0], null, this.injector);
this.tabPortalHost.attach(portal);
When wrapping the last line in a setTimeout
, the code works as expected. 将最后一行包装在setTimeout
,代码将按预期工作。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.