首页 文章

angular 2 - 如何使用服务的输入/输出动态创建组件实例并将其单独注入DOM?

提问于
浏览
5

在角度2中创建动态组件时,我发现此过程需要ViewContainerRef才能将新创建的组件添加到DOM .

Angular 2 dynamic tabs with user-click chosen components https://www.lucidchart.com/techblog/2016/07/19/building-angular-2-components-on-the-fly-a-dialog-box-example/

在将输入和输出传递给那些动态创建的组件时,我在上面的第二个链接中找到了答案:https://codedump.io/share/kQakwDKNu0iG/1/passing-input-while-creating-angular-2-component-dynamically-using-componentresolver

但是,如果我要创建一个名为shape.service的服务,其中包含使用bgColor等输入返回不同形状组件的函数,我不知道该服务如何在不指定DOM位置的情况下创建组件,以及容器组件如何接收这个返回的组件(可能是它的类型将是ComponentRef)来自服务并将其注入DOM容器组件指定 .

例如,服务包含一个功能:

getCircle(bgColor:string): ComponentRef<Circle> {
    let circleFactory = componentFactoryResolver.resolveComponentFactory(CircleComponent);
    let circleCompRef = this.viewContainerRef.createComponent(circleFactory);
    circleCompRef.instance.bgColor = bgColor;

    return circleCompRef;
}

第一个问题在这里提出,如何让 this.viewContainerRef 指向同时没有?我导入viewContainerRef的原因是动态创建组件 .

第二个问题是在容器组件从服务接收特定于输入的 componentRef 之后,它将如何注入其DOM?

提前致谢!

UPDATE: 我认为上面的问题不是't specific enough. I' m,其中:

  • 父组件调用服务并获取componentRef / s,

  • 创建一个包含componentRef / s的对象以及其他一些数据,并将创建的对象存储到数组中

  • 将其作为输入传递给子项,

  • 让每个孩子将componentRef注入其DOM,并以其他方式使用对象中的其余数据 .

这意味着服务调用组件不知道这些componentRef将被注入的位置 . 简而言之,我需要可以随时随地注入的独立组件对象 .

我已经好几次读过rumTimeCompiler解决方案,但我真的不知道它是如何工作的 . 与使用viewContainerRef创建组件相比,似乎有太多工作要做 . 如果我找不到其他解决方案,我会深入研究一下......

1 回答

  • 6

    也许这个plunker会帮助你:https://plnkr.co/edit/iTG7Ysjuv7oiDozuXwj6?p=preview

    据我所知,您需要 ViewContainerRef 服务 . 但是调用您的服务的组件可以将其添加为参数,如下所示:

    (只是一个服务..请参阅plunker完整的工作示例)

    import { Injectable, ViewContainerRef, ReflectiveInjector, ComponentFactoryResolver, ComponentRef } from '@angular/core';
    
    import { HelloComponent, HelloModel } from './hello.component';
    
    @Injectable()
    export class DynamicCompService {
    
      constructor (private componentFactoryResolver: ComponentFactoryResolver) { }
    
      public createHelloComp (vCref: ViewContainerRef, modelInput: HelloModel): ComponentRef {
    
        let factory = this.componentFactoryResolver.resolveComponentFactory(HelloComponent);
    
        // vCref is needed cause of that injector..
        let injector = ReflectiveInjector.fromResolvedProviders([], vCref.parentInjector);
    
        // create component without adding it directly to the DOM
        let comp = factory.create(injector);
    
        // add inputs first !! otherwise component/template crashes ..
        comp.instance.model = modelInput;
    
        // all inputs set? add it to the DOM ..
        vCref.insert(comp.hostView);
    
        return comp;
      }
    }
    

相关问题