如何使用服务的输入/输出动态创建组件实例并将其分别注入DOM? [英] How to dynamically create component instance with input/output from a service and inject it to DOM separately?

查看:140
本文介绍了如何使用服务的输入/输出动态创建组件实例并将其分别注入DOM?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在Angular 2中创建动态组件时,我

In creating dynamic components in Angular 2, I found out that this process requires ViewContainerRef in order to add newly created component to DOM.

在将@Input@Output传递给那些动态创建的组件时,我在上面的第二个链接和

And in passing @Input and @Outputto those dynamically created components, I found the answer in the second link above and here.

但是,如果我要创建一个名为shape.service的服务,其中包含返回带有@Input之类的不同@Input形状组件的函数,那么我不知道该服务如何在不指定DOM位置的情况下创建组件,以及容器组件如何从服务接收此返回的组件(可能其类型为ComponentRef)并将其注入到DOM容器组件指定的容器中.

However, if I were to create a service named shape.service that contains functions returning different shape components with some @Input like bgColor, I don't know how this service will create a component without specifying DOM location, and how the container-component receives this returned component (probably its type will be ComponentRef) from the service and injects it to the DOM container-component specifies.

例如,服务包含方法:

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的原因是为了动态创建组件.

First question rises here, how do I make this.viewContainerRef point to no where for the meantime? The reason why I'm importing ViewContainerRef is to create component dynamically.

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

Second question is after container-component receives input-specificcomponentRef from the service, how will it inject to its DOM?

更新: 我认为上面的问题还不够具体.我处于以下情况:

UPDATE: I think my question above wasn't specific enough. I'm in a situation where:

  1. 父组件调用服务并获取componentRef/s,
  2. 创建一个包含componentRef/s和其他一些数据的对象,并将这些创建的对象存储到数组中
  3. 将其作为@Input传递给其子代
  4. 然后让每个子对象将componentRef注入其DOM并以其他方式使用对象中的其余数据.
  1. A parent component calls the service and gets the componentRef/s,
  2. Creates an object including componentRef/s together with some other data and stores those created object/s into array
  3. Passes it to its children as @Input,
  4. And let each child inject componentRef to its DOM and use rest of the data in the object in other way.

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

That means the service calling component has no idea where those componentRef will get injected. In short, I need independent component objects that can be injected to anywhere, anytime I want.

我已经多次阅读rumTimeCompiler解决方案,但是我并没有真正了解它是如何工作的.与使用viewContainerRef创建组件相比,似乎有太多工作要做.如果找不到其他解决方案,我将做进一步探讨...

I'm reading the rumTimeCompiler solution several times already but I don't really get how that really works. It seems like there's too much work compared to component creation using viewContainerRef. I'll dig into that more if I find no other solution...

推荐答案

也许这个矮子可以帮助您: https://plnkr.co/edit/iTG7Ysjuv7oiDozuXwj6?p=preview

Maybe this plunker will help you: https://plnkr.co/edit/iTG7Ysjuv7oiDozuXwj6?p=preview

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

As far as i know, you will need the ViewContainerRef inside of your service. But the component calling your service can add it as an parameter, like this:

(只是一项服务.有关完整的工作示例,请参见plunker)

(just a the service.. see plunker for full working example)

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;
  }
}

这篇关于如何使用服务的输入/输出动态创建组件实例并将其分别注入DOM?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆