Mi aplicación tiene un NameService que contiene el nombre.
Hay dos componentes secundarios de App, Navbar y TheContent que hacen referencia a este servicio. Siempre que cambie el nombre en el servicio, quiero que se actualice en los otros dos componentes. ¿Cómo puedo hacer esto?
import {Component, Injectable} from 'angular2/core' // Name Service @Injectable() class NameService { name: any; constructor() { this.name = "Jack"; } change(){ this.name = "Jane"; } } // The navbar @Component({ selector: 'navbar', template: '<div>This is the navbar, user name is {{name}}.</div>' }) export class Navbar { name: any; constructor(nameService: NameService) { this.name = nameService.name; } } // The content area @Component({ selector: 'thecontent', template: '<div>This is the content area. Hello user {{name}}. <button (click)=changeMyName()>Change the name</button></div>' }) export class TheContent { name: any; constructor(public nameService: NameService) { this.name = nameService.name; } changeMyName() { this.nameService.change(); console.log(this.nameService.name); } } @Component({ selector: 'app', providers: [NameService], directives: [TheContent, Navbar], template: '<navbar></navbar><thecontent></thecontent>' }) export class App { constructor(public nameService: NameService) { } }Proporcione un evento en el servicio y suscríbase a él en los componentes:
@Injectable() class NameService { name: any; // EventEmitter should not be used this way - only for `@Output()`s //nameChange: EventEmitter<string> = new EventEmitter<string>(); nameChange: Subject<string> = new Subject<string>(); constructor() { this.name = "Jack"; } change(){ this.name = 'Jane'; this.nameChange.next(this.name); } } export class SomeComponent { constructor(private nameService: NameService) { this.name = nameService.name; this._subscription = nameService.nameChange.subscribe((value) => { this.name = value; }); } ngOnDestroy() { //prevent memory leak when component destroyed this._subscription.unsubscribe(); } } Ver también
angular.io - INTERACCIÓN DE COMPONENTES - Padres e hijos se comunican a través de un servicio
Dado que el name en NameService es un tipo primitivo, obtendrá una instancia diferente en el servicio y sus componentes. Cuando cambia el name en NameService , las propiedades del componente aún tienen el valor inicial y el enlace no funciona como se esperaba.
Debe aplicar la "regla de puntos" angular1 aquí y enlazar a un tipo de referencia. Cambie NameService para almacenar un objeto que contenga el nombre.
export interface Info { name:string; } @Injectable() class NameService { info: Info = { name : "Jack" }; change(){ this.info.name = "Jane"; } } Puede vincular a este objeto y obtener actualizaciones de la propiedad de name automáticamente.
// The navbar @Component({ selector: 'navbar', template: '<div>This is the navbar, user name is {{info.name}}.</div>' }) export class Navbar { info: Info; constructor(nameService: NameService) { this.info = nameService.info; } }Creo que la solución aportada por Günter es la mejor.
Dicho esto, debe tener en cuenta que los servicios de Angular2 son singleton que tienen lugar en un árbol de inyectores. Esto significa que:
bootstrap ), la instancia puede ser compartida por todos los elementos (componentes y servicio).providers ), la instancia será específica para el componente y sus subcomponentes.Para obtener más detalles sobre este aspecto, puede consultar el documento "Inyección de dependencia jerárquica": https://angular.io/docs/ts/latest/guide/hierarchical-dependency-injection.html
Espero que te ayude Thierry