2017-09-04 2 views
2

In meiner Angular App habe ich eine globale Variable namens AppInjector, die den Injektor zurückgibt. Diese Variable wird in AppModule gesetzt.Angular 2: Globaler AppInjector. Wie vermeiden Warnung "zirkuläre Abhängigkeit"

export let AppInjector: Injector; 

@NgModule({ 
    declarations: [ 
     AppComponent, 
    ], 
    bootstrap: [AppComponent], 
}) 
export class AppModule { 

    constructor(private injector: Injector) { 
     AppInjector = this.injector; 
    } 
} 

Ich habe einige Hilfsfunktionen, die mit Hilfe des AppInjector einen besonderen Service erhalten. Die Hilfsfunktionen befinden sich in separaten Dateien und gehören keiner Komponente an. Zum Beispiel:..?

function initNodeTemplate() { 

    diagram.nodeTemplateMap.add(NodeCategory.Question, 
     GO(go.Node, "Auto", 
      { 
       click: (evt, obj) => {(AppInjector.get(MyService) as MyService).myFunction(obj)}, 
      }, 
      // other stuff ... 
     )); 
} 

Das Problem ist, dass der Winkel Compiler mich über eine zirkuläre Abhängigkeit warnt (wegen der AppInjectorWARNING in Circular dependency detected: src\app\app.module.ts -> src\app\frame\frame.module.ts -> src\app\designer\designer.module.ts -> src\app\designer\designer.component.ts -> src\app\designer\helpers\templates.helper.ts -> src\app\app.module.ts

Wie kann ich diese Warnung loswerden Ich weiß, dass Ich kann einen Service in eine Komponente injizieren und dann den Service an die Hilfsfunktion übergeben. In diesem Fall könnte ich detailService als Parameter an initNodeTemplate() übergeben und so brauche ich nicht mehr die AppInjector. Aber ich möchte vermeiden, meine Funktion zu versauen Parameter mit diesen Diensten.

+0

Brechen Sie den Zyklus. Schwer zu sagen, genau wie ohne den Code zu sehen, der es verursacht. Siehe auch https://stackoverflow.com/questions/41585863/angular2-injecting-services-in-custom-errorhandler/41585902#41585902 –

Antwort

1

Eine einfache Möglichkeit, dies zu vermeiden, ist, dass Ihre Klassen AppInjector von etwas anderem importieren als die AppModule, die genau diese Klassen deklariert/bereitstellt.

Fügen Sie also einen Helfer, z. app-injector.ts:

import {Injector} from '@angular/core'; 

/** 
* Allows for retrieving singletons using `AppInjector.get(MyService)` (whereas 
* `ReflectiveInjector.resolveAndCreate(MyService)` would create a new instance 
* of the service). 
*/ 
export let AppInjector: Injector; 

/** 
* Helper to access the exported {@link AppInjector}, needed as ES6 modules export 
* immutable bindings; see http://2ality.com/2015/07/es6-module-exports.html 
*/ 
export function setAppInjector(injector: Injector) { 
    if (AppInjector) { 
     // Should not happen 
     console.error('Programming error: AppInjector was already set'); 
    } 
    else { 
     AppInjector = injector; 
    } 
} 

Und dann in Ihrem AppModule, zu verwenden:

import {Injector} from '@angular/core'; 
import {setAppInjector} from './app-injector'; 

export class AppModule { 
    constructor(injector: Injector) { 
     setAppInjector(injector); 
    } 
} 

... während in den anderen Klassen verwenden nach wie vor:

import {AppInjector} from './app-injector'; 
const myService = AppInjector.get(MyService); 

(Es besteht keine Notwendigkeit sein sollte Für das manuelle Casting der Ergebnisse sollte der Compiler den Typ Ihres Dienstes kennen.)

+0

Danke für Ihre Antwort. Das funktioniert nicht für mich. Immer noch die gleichen Fehler :( –

+0

Dann würde ich vermuten, dass der Fehler nicht (oder nicht mehr) mit der Verwendung des globalen 'AppInjector' verbunden ist, oder Sie den jetzt veralteten Import für' AppModule' in Ihren Komponenten nicht entfernen konnten Fehler wirklich genau das gleiche? – Arjan

+0

Es funktioniert perfekt! Danke – nim4n

Verwandte Themen