我正在尝试在Angular2应用程序中为popover类型控制器构建一个组件工厂。
我现在正在使用它,我将所有依赖项和我的组件传递给控制器,并通过componentFactoryResolver.resolveComponentFactory创建,它运行良好。
我希望调用者不必传递对依赖项的引用,但无法弄清楚如何管理它。我尝试过使用ReflectiveInjector.resolveAndCreate,但似乎无法管理。
如何设置它以便我可以访问ComponentFactoryResolver和ViewContainerRef而无需通过此服务的所有使用者导入和传递?请参阅下面的当前设置
呼叫者/演示
myPopover = new PopoverController(this.componentFactoryResolver, this.viewContainerRef, MyComponent);
PopoverController
constructor (private componentFactoryResolver: ComponentFactoryResolver, private viewContainerRef: ViewContainerRef, private myComponent: Component){
let factory = this.componentFactoryResolver.resolveComponentFactory(<Type<Component>>myComponent);
let res = this.viewContainerRef.createComponent(factory);
}
以上工作非常好,并且很好地构建了myComponent,我只是不必继续将refs传递给我的调用者的ComponentFactoryResolver和viewContainer,理论上他们不应该关心那些服务。
我尝试了类似下面的内容,但没有设法让它发挥作用
var injector = ReflectiveInjector.resolveAndCreate([ComponentFactoryResolver, ViewContainerRef]);
答案 0 :(得分:2)
ReflectiveInjector
会创建一个新的投影机实例,但不适用。注射器实例应该通过引用从另一个注射器传递。如果没有可用的注射器实例,则可以使用this technique获取根注入器(并且可能表明设计存在问题)。
ViewContainerRef
不是正常@angular/core
服务,它不会引用单例实例,而是引用特定于特定组件的实例。它不能用注射器检索。
当然,viewContainerRef
需要通过引用传递。
It has injector
property,这意味着不需要与viewContainerRef
一起传递其他依赖项,可以就地检索它们:
const { injector } = viewContainerRef;
const componentFactoryResolver = injector.get(ComponentFactoryResolver);
答案 1 :(得分:0)
受上面接受的答案的启发,我找到了一种方法,使用Factory Providers比依赖ViewContainerRef
和ComponentFactoryResolver
类之间的关系更通用地完成此操作,尽管我的代码具有讽刺意味也需要它们:))
<强> my.service.provider.ts 强>
import {MyService} from './my.service';
import {
ComponentFactoryResolver,
RendererFactory2,
ViewContainerRef
} from '@angular/core';
const myServiceFactory = (rendererFactory, viewContainer, componentFactoryResolver) => {
return new MyService(rendererFactory, viewContainer, componentFactoryResolver);
};
export const MyServiceProvider = {
provide: MyService,
useFactory: myServiceFactory,
deps: [RendererFactory2, ViewContainerRef, ComponentFactoryResolver]
};
摘自需要服务的组件
@Component({
...
providers: [MyServiceProvider],
...
})