动态创建的组件

时间:2017-11-17 15:41:13

标签: angular typescript angular-material2 angular5

我正面临Angular的问题以及来自CdkPortal的{​​{1}} / CdkPortalHost
我创建了一项服务,允许我注册一个具有给定名称的@angular/cdk并随时设置它CdkPortalHost

服务如下:

Component

然后我注册了这样的PortalHost:

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的Component的子组件,我像这样设置动态组件:

@ViewChild(PortalHostDirective)
private portalHost : PortalHostDirective;

public ngAfterContentInit() {
    this.dynamicComponentService.register("Location", this.portalHost);
}

出于测试目的,我使用MyDynamicComponent的简单模板:

public ngAfterContentInit() {
    this.dynamicComponentService.setComponent("Location", MyDynamicComponent);
}

现在,当我运行App时,出现以下错误:

<div *ngIf="true">Test</div>

我见过几个类似的问题,但是&#34; window.setTimeout&#34; -Workaround对我来说不起作用。
我还为PortalHost-Registration和Component-Creation尝试了不同的生命周期钩子,但结果总是一样......

我使用的是Angular 5.0.1和Material / CDK 5.0.0-rc0。

我错过了什么或这是一个错误吗? 它与Angular/Material#5268

有关

1 个答案:

答案 0 :(得分:0)

ngAfterContentInit对于门户网站插座的更改检测生效可能为时过早。在注册门户网站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);

setTimeout中包装最后一行时,代码按预期工作。