Angular 2 DI:将输入绑定传递给工厂提供商的deps

时间:2017-03-04 07:23:00

标签: angular angular2-injection angular2-inputs

是否有一种简单的方法将输入绑定注入提供程序工厂的deps数组?下面显然不起作用。

const myServiceFactory = (object: any) => {
   //...
};

@Component({
    // ...
    inputs: ['object'],
    providers: [
        {
            provide: Object,
            useValue: object,
        },
        {
            provide: MyService,
            useFactory: myServiceFactory,
            deps: [Object]
        }
    ]
})

2 个答案:

答案 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 ]
    },