Angular Inject параметризованный провайдер - PullRequest
0 голосов
/ 16 октября 2019

У меня есть сервис, подобный этому

@Injectable()
export class MyService {
  constructor(private store: Store, @Optional() type: string){}

  static forType(type: string) {
    return { provide: MyService, deps: [Store], useFactory: factoryFn.bind(type) }  
  }

}

export function factoryFn(store: Store, type: string) {
  return new MyService(store, type);
}

, и я хочу внедрить его в мой компонент, как этот

@Component{ 
  providers: [MyService.forType('hello')]
}
export class MyComponent {}

, но это дает мне следующую ошибку

Function calls are not supported in decorators but 'factoryFn' was called in 'MyService'
'MyService' calls 'factoryFn'.

Причина, по которой я хочу использовать его как статический метод в реальной службе, заключается в том, что я не хочу, чтобы компонент знал, какие зависимости нужны MyService. MyService также используется во многих разных местах, поэтому таким образом я также избегаю дублирования.

Есть ли способ обмануть Angular в разрешении вызова функции?

С уважением, Бенедикт

1 Ответ

0 голосов
/ 16 октября 2019

После некоторых поисков я нашел изящный обходной путь, как это можно сделать. Мы можем создать токен на основе нашего желаемого параметра и затем использовать этот токен в Сервисе. Чтобы автоматически внедрить и службу, и ее токен, мы можем использовать тот факт, что Angular выравнивает массив провайдеров, поэтому мы можем просто вернуть массив с обоими.

export const MY_TOKEN = new InjectionToken<string>('MY_TOKEN');
@Injectable()
export class MyService {
  constructor(private store: Store, @Inject(MY_TOKEN) type: string){}

  static forType(type: string) {
    return [{ provide: MY_TOKEN, useValue: type}, MyService]
  }
}

Итак, в итоге мы получимсинтаксис использования сервиса и все работает, также в AOT:

@Component{ 
  providers: [MyService.forType('hello')]
}
export class MyComponent {}
...