Угловой динамический 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, если вы совпадете по именам токенов. Многие библиотеки объявляют токен "документа" в качестве примера. Так что вы не хотите использовать строковые имена. Как столкновение было бы чрезвычайно трудно найти и исправить.