Понимание контекста Angular Injection
May 02 2023
В последних версиях Angular появилась функция inject(), которая позволяет нам получить ссылку на провайдера функциональным способом, а не с помощью метода Injector.get().

Angular представил эту inject()
функцию в последних версиях, которая позволяет нам получить ссылку на провайдера функциональным способом, а не с помощью метода Injector.get()
. Однако, если вы использовали его или библиотеку, которая использует его под капотом, вы могли столкнуться со следующей ошибкой:
inject() must be called from an injection context
such as a constructor, a factory function, a field initializer,
or a function used with `runInInjectionContext`.
В Angular есть две глобальные переменные, которые могут хранить injector
в определенный момент времени: одна для Injector
и одна для NodeInjector
. Вот фрагменты кода для обоих:
let _currentInjector = undefined;
export function getCurrentInjector() {
return _currentInjector;
}
export function setCurrentInjector(injector: Injector|undefined|null {
const former = _currentInjector;
_currentInjector = injector;
return former;
}
let _injectImplementation
export function getInjectImplementation() {
return _injectImplementation;
}
export function assertInInjectionContext(debugFn: Function): void {
if (!getInjectImplementation() && !getCurrentInjector()) {
throw new RuntimeError(
RuntimeErrorCode.MISSING_INJECTION_CONTEXT,
ngDevMode &&
(debugFn.name +
'() can only be used within an injection context such as a constructor, a factory function, a field initializer, or a function used with `runInInjectionContext`'));
}
}
import {
ElementRef,
assertInInjectionContext,
inject,
} from '@angular/core';
export function injectNativeElement<T extends Element>(): T {
assertInInjectionContext(injectNativeElement);
return inject(ElementRef).nativeElement;
}
- В
factory
функции, указанной дляInjectionToken
:
export const FOO = new InjectionToken('FOO', {
factory() {
const value = inject(SOME_PROVIDER);
return ...
},
});
@Component({
providers: [
{
provide: FOO,
useFactory() {
const value = inject(SOME_PROVIDER);
return ...
},
},
]
})
export class FooComponent {}
@Component({})
export class FooComponent {
foo = inject(FOO);
constructor(private ngZone: NgZone = inject(NgZone)) {
const bar = inject(BAR);
}
}
runInInjectionContext
функции:import { runInInjectionContext } from '@angular/core';
export class FooComponent {
ngOnInit() {
runInInjectionContext(this.injector, () => {
console.log(
'I can access the NodeInjector using inject()',
inject(ElementRef)
);
})
}
Подпишитесь на меня в Medium или Twitter , чтобы узнать больше об Angular и JS!