Den Angular-Injection-Kontext verstehen

May 02 2023
Angular hat in neueren Versionen die Funktion inject() eingeführt, die es uns ermöglicht, auf funktionale Weise einen Verweis auf einen Anbieter zu erhalten, anstatt die Methode Injector.get() zu verwenden.

Angular hat die inject()Funktion in neueren Versionen eingeführt, die es uns ermöglicht, auf funktionale Weise einen Verweis auf einen Anbieter zu erhalten, anstatt die Injector.get()Methode zu verwenden. Wenn Sie es jedoch oder eine Bibliothek, die es unter der Haube verwendet, verwendet haben, ist möglicherweise der folgende Fehler aufgetreten:

inject() must be called from an injection context 
such as a constructor, a factory function, a field initializer, 
or a function used with `runInInjectionContext`.

injectorAngular verfügt über zwei globale Variablen, die zu einem bestimmten Zeitpunkt eine enthalten können : eine für an Injectorund eine für NodeInjector. Hier sind die Codeausschnitte für beide:

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;
}

  • In der factoryfür an angegebenen Funktion 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);
      }
    }
    

  • Innerhalb einer Funktion, die mit der Funktion ausgeführt wird runInInjectionContext:
  • import { runInInjectionContext } from '@angular/core';
    
    export class FooComponent {
      ngOnInit() {
        runInInjectionContext(this.injector, () => {
          console.log(
            'I can access the NodeInjector using inject()',
            inject(ElementRef)
          );
        })
    }
    

Folgen Sie mir auf Medium oder Twitter, um mehr über Angular und JS zu erfahren!