首页 文章

Angular CDK:如何在ComponentPortal中设置输入

提问于
浏览
14

我想使用材料CDK中的新Portal在表单的多个部分中注入动态内容 .

我有一个复杂的表单结构,目标是有一个表单,指定子组件可以(或不)注入模板的多个位置 .

也许CDK门户网站不是最好的解决方案?

我尝试了一些东西,但我确定这不是做法:https://stackblitz.com/edit/angular-yuz1kg

我也尝试了 new ComponentPortal(MyPortalComponent) ,但我们如何设置输入呢?通常是 componentRef.component.instance.myInput

3 回答

  • 3

    您可以创建自定义注入器并将其注入您创建的组件门户 . -

    createInjector(dataToPass): PortalInjector {
        const injectorTokens = new WeakMap();
        injectorTokens.set(CONTAINER_DATA, dataToPass);
        return new PortalInjector(this._injector, injectorTokens);
      }
    

    CONTAINER_DATA是由 - 创建的自定义注入器(InjectorToken) -

    export const CONTAINER_DATA = new InjectionToken<{}>('CONTAINER_DATA');
    

    要消耗创建的注射器,请使用 -

    let containerPortal = new ComponentPortal(ComponentToPort, null, this.createInjector({
              data1,
              data2
            }));
    
       overlay.attach(containerPortal);
    

    overlay是OverlayRef的实例(这是Portal Outlet)

    在“ComponentToPort”中,您需要注入创建的注入器 -

    @Inject(CONTAINER_DATA) public componentData: any
    

    更多相关信息 -

  • -1

    您可以使用在ComponentPortal的第3个参数上传递的特定注入器将数据注入ComponentPortal(修复语法问题:无法解析组件的所有参数:([object Object],[object Object],?) .

    export const PORTAL_DATA = new InjectionToken<{}>('PortalData');
    
    class ContainerComponent {
      constructor(private injector: Injector, private overlay: Overlay) {}
    
      attachPortal() {
        const componentPortal = new ComponentPortal(
          ComponentToPort,
          null,
          this.createInjector({id: 'first-data'})
        );
        this.overlay.create().attach(componentPortal);
      }
    
      private createInjector(data): PortalInjector {
    
        const injectorTokens = new WeakMap<any, any>([
          [PORTAL_DATA, data],
        ]);
    
        return new PortalInjector(this.injector, injectorTokens);
      }
    }
    
    class ComponentToPort {
      constructor(@Inject(PORTAL_DATA) public data ) {
        console.log(data);
      }
    }
    
  • 13

    可以通过以下方式设置组件输入(或以可观察的方式绑定到输出):

    portal = new ComponentPortal(MyComponent);
    this.portalHost = new DomPortalHost(
          this.elementRef.nativeElement,
          this.componentFactoryResolver,
          this.appRef,
          this.injector
        );
    
    const componentRef = this.portalHost.attach(this.portal);
    componentRef.instance.myInput = data;
    componentRef.instance.myOutput.subscribe(...);
    componentRef.changeDetectorRef.detectChanges();
    

相关问题