是否有一种简单的方法将输入绑定注入提供程序工厂的deps数组?下面显然不起作用。
const myServiceFactory = (object: any) => {
//...
};
@Component({
// ...
inputs: ['object'],
providers: [
{
provide: Object,
useValue: object,
},
{
provide: MyService,
useFactory: myServiceFactory,
deps: [Object]
}
]
})
答案 0 :(得分:5)
作为可能的解决方案,您可以尝试这样做:
const myServiceFactory = (self: Child) => {
return new MyService(self.param);
};
class MyService {
constructor(private param: string) {}
}
@Component({
selector: 'child',
template: `{{ param }}`,
providers: [
{
provide: MyService,
useFactory: myServiceFactory,
deps: [Child]
}
]
})
export class Child {
@Input() param: any;
constructor(private inj: Injector) { }
ngOnInit() { // or ngOnChanges
let service = this.inj.get(MyService);
}
}
<强> Plunker Example 强>
答案 1 :(得分:0)
可接受的答案效果很好,但是如果您的组件“提供”了多个相互依赖的依赖关系,那么事情就会变得复杂得多。
如果您已经大量使用可观察对象,那么另一种可行的方法是提供一个LAZY_ID
令牌,该令牌实际上是一个ReplaySubject<number>
(或您需要的任何类型)。
在您的ngOnInit()
中,您只需调用this.lazyID.next(this.id)
,以通过ReplaySubject
传递的值更新@Input
。
此外,您还可以将此LAZY_ID
与提供程序工厂一起使用,以创建主要的依赖项。
免责声明:我认为这不是解决此问题的好方法。它可能变得笨拙,但有时可能会起作用!
这是一个简化的示例-欢迎改进:
export const LAZY_ID = new InjectionToken<ReplaySubject<number>>('LAZY_ID');
export const LazyIDFactory = () =>
{
return new ReplaySubject<number>(1);
}
export const productDataFromLazyIDFactory = (productService: ProductService, id$: ReplaySubject<number>) =>
{
// Create your 'ProductData' from your service and id$
// So yes - the catch here is your ProductData needs to take an observable
// as an input - which only really works if you're extensively using observables
// everywhere. You can't 'wait' for the result here since the factory must return
// immediately
}
然后在您的@Component
providers: [
// creates our ReplaySubject to hold the ID
{
provide: LAZY_ID,
useFactory: LazyIDFactory
},
{
provide: ProductData,
useFactory: productDataFromLazyIDFactory,
deps: [ ProductService, LAZY_ID ]
},