Угловой динамический DI со строковым токеном

Похоже, что Angular 6 (4+?) Требует, чтобы объекты токенов были уникальными для работы DI. Тем не менее, я хочу использовать динамический токен, предоставляемый из шаблона HTML-кода, который позволит моей новой директиве разрешать службу по имени.

На данный момент код:

this.service = this.injector.get(new InjectionToken<IServiceRef>(tokenName));

Сбой с:

Error: StaticInjectorError(AppModule)[InjectionToken the_token_name]: 

Когда я заменил свой код на старую функцию Injector.get со старым ограничением (в угловом 4), все заработало, потому что инжектор сравнивает имена (и я предоставляю сервис в представлении под этим именем...). Однако с новым DI я не могу добиться того, чего хочу.

Итак, как решать?

1 ответ

Решение

Вы должны использовать глобальный объект хранения для своих токенов. Я рекомендую вам использовать карту.

export const tokens: Map<string, InjectionToken<IServiceRef>> = new Map();
tokens.set('tokenName', new InjectionToken<IServiceRef>('tokenName'));

Вы должны использовать объект карты, чтобы объявить провайдера.

@NgModule({
     providers: [
          {provide: tokens.get('tokenName'), useValue: new Service()}
     ]
 );

Теперь вы можете искать токен через строковое значение.

this.service = this.injector.get(tokens.get(the_token_name));

Я не знал, что это изменилось в Angular 6, но я помню, что в документации сказано, что токены являются эталонными. Это означает, что DI использует === сопоставить зависимости.

Вы получите коллизии в DI, если вы совпадете по именам токенов. Многие библиотеки объявляют токен "документа" в качестве примера. Так что вы не хотите использовать строковые имена. Как столкновение было бы чрезвычайно трудно найти и исправить.

Другие вопросы по тегам