如何使用服务的输入/输出动态创建组件实例并将其分别注入DOM? [英] How to dynamically create component instance with input/output from a service and inject it to DOM separately?
问题描述
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 @Output
to 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:
- 父组件调用服务并获取componentRef/s,
- 创建一个包含componentRef/s和其他一些数据的对象,并将这些创建的对象存储到数组中
- 将其作为
@Input
传递给其子代 - 然后让每个子对象将componentRef注入其DOM并以其他方式使用对象中的其余数据.
- A parent component calls the service and gets the componentRef/s,
- Creates an object including componentRef/s together with some other data and stores those created object/s into array
- Passes it to its children as
@Input
, - 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屋!