page navigationend example change angular

angular - navigationend - Servicios dependiendo el uno del otro



router events angular 6 (11)

Actualicé esta solución para trabajar con Angular> 4. Usando la clase Injector puede inyectar un servicio en otro servicio

import { Injector } from ''@angular/core''; import { TempService } from ''./tmp''; @Injectable() export class Temp2Service { private tempService: any; constructor (private injector: Injector) { } public funcA() { this.tempService = this.injector.get(TempService); this.tempService.doSomething(); } }

En mi aplicación Angular 2, tengo dos servicios que dependen el uno del otro (métodos de llamada del servicio A desde el servicio B y viceversa).

Aquí están los códigos relevantes:

app.component.ts :

import {Component} from ''angular2/core''; import {TempService} from ''../services/tmp''; import {Temp2Service} from ''../services/tmp2''; @Component({ selector: ''my-app'', templateUrl: ''app/app/app.component.html'', providers: [TempService, Temp2Service] }) export class AppComponent { (...) }

Servicio 1:

import {Injectable} from ''angular2/core''; import {Temp2Service} from ''./tmp2''; @Injectable() export class TempService { constructor (private _sessionService: Temp2Service) {} }

Servicio 2:

import {Injectable} from ''angular2/core''; import {TempService} from ''./tmp''; @Injectable() export class Temp2Service { constructor (private _sessionService: TempService) {} }

La ejecución de la aplicación genera el siguiente error:

EXCEPCIÓN: No se pueden resolver todos los parámetros para ''Temp2Service'' (indefinido). Asegúrese de que todos los parámetros estén decorados con Inject o tengan anotaciones de tipo válidas y que ''Temp2Service'' esté decorado con Injectable

Al comentar el constructor en uno de los servicios, la aplicación funciona bien. Entonces, supongo que la "referencia cruzada" de los dos servicios está causando el problema.

¿Tienes idea de lo que está pasando mal aquí? ¿O mi enfoque ya está mal?


Es una dependencia circular y desafortunadamente es un problema fundamental de informática, o problema de información, algo que Angular no puede resolver. Intenta hacer algo como esto en su lugar:

export class ServiceA{ constructor(private b: ServiceB){ b.setA(this); } } export class ServiceB { private a: ServiceA constructor(){ } setA(a){ this.a = a; } }

esa es probablemente la mejor manera de hacerlo.


Esta es una dependencia circular llamada. No es un problema con Angular2 en sí. No está permitido en ningún idioma que yo sepa.

Deberá refactorizar su código para eliminar esta dependencia circular. Probablemente necesitará dividir uno de estos servicios en uno nuevo.

Si sigue el principio de responsabilidad única, encontrará que no entrará en la trampa de dependencia circular.



La clave aquí no es inyectar el servicio a través del constructor, sino utilizar setters y getters explícitos. Usaría el siguiente patrón en Angular 4:

app.component.ts

import { FooService } from ''./foo/foo.service''; import { BarService } from ''./bar/bar.service''; export class AppComponent { constructor(public fooService: FooService, public barService: BarService) { this.fooService.setBarService(barService); } }

foo.service.ts

@Injectable() export class FooService { barService: any; constructor(){ } setBarService(barService: any): void { this.barService = barService; } getBarService(): any { return this.barService; } }


La inyección del constructor evita dependencias circulares.

Se puede dividir inyectando el Injector y solicitando una dependencia imperativa como:

private payrollService:PayrollService; constructor(/*private payrollService:PayrollService*/ injector:Injector) { setTimeout(() => this.payrollService = injector.get(PayrollService)); }

Ver también Inyección de dependencia circular angular 2


Podemos resolver la función forwordRef para resolver este problema.

// Permite hacer referencia a referencias que aún no están definidas.

@Inject (forwardRef (() => MyService)) httpProxy privado: MyService


Si está utilizando Angular 2 y necesita una dependencia circular para llamar funciones entre sí en algunos eventos, puede usar Observables y suscribirlos en el Servicio en el que inyectó el otro servicio.

Pequeño ejemplo: -

@Injectable() class Service1{ observeEvents(){ return Obsevable.create((o)=>{ //store `o` it in any class variable //whenever you want to call function of Service2 from this class, do this `o.next(''method_name'');` }); } } @Injectable() class Service2{ constructor(private service1: Service1){ this.service1.subscribe((method)=>{ this[method](); }); } }


Todo lo que traté de arreglar la advertencia de dependencia circular con setTimeout o el uso del inyector y mover la inyección del constructor a otra función no funcionó para mí con angular 7.

Aquí está mi solución de trabajo:

Creé otro servicio solo para mantener la referencia del servicio al primer servicio:

@Injectable() export class AnotherService { private _service: AService; get service(): AService { return this._service; } set service(service: AService) { this._service = service; } }

Entonces puedo usarlo así:

@Injectable() export class AService { constructor(private anotherService: AnotherService) { anotherService.service = this; } ... }

y aquí:

@Injectable() export class BService { private aService: AService; constructor(private injector: Injector) { const anotherService = injector.get(AnotherService); this.aService = anotherService.service; } ... }



puede intentar llamar a NEW en uno de los servicios si no es aceptable tener un singleton. me gusta

this._sessionService = new TempService(this);

Este fue el enfoque que tomé, ya que ninguno de los servicios utilizaba variables miembro indefinidas.