使用angular2更新服务中组件的可变更改

我的应用程序有一个NameService名称。

App有两个子组件,Navbar和TheContent引用了这个服务。 每当名称在服务中更改,我希望它在其他两个组件中更新。 我怎样才能做到这一点?

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) { } } 

在服务中提供一个事件并在组件中订阅它:

 @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(); } } 

也可以看看
angular.io – 组件交互 – 父母和孩子通过服务进行交stream

由于NameService中的name是原始types,因此您将在服务和组件中获得不同的实例。 当您在NameService更改name时,组件属性仍具有初始值,并且绑定不能按预期工作。

您应该在这里应用angular1“点规则”并绑定到引用types。 更改NameService以存储包含名称的对象。

 export interface Info { name:string; } @Injectable() class NameService { info: Info = { name : "Jack" }; change(){ this.info.name = "Jane"; } } 

您可以绑定到此对象并自动更新name属性。

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

我认为由Günter提供的解决scheme是最好的。

这就是说,你必须意识到,Angular2服务是单向的,发生在注入器树中。 这意味着:

  • 如果您在应用程序级别(在bootstrap方法的第二个参数内)定义服务,则实例可以由所有元素(组件和服务)共享。
  • 如果您在组件级别(在providers属性中)定义服务,那么实例将特定于组件及其子组件。

有关这方面的更多细节,你可以看看“层次dependency injection”文档: https : //angular.io/docs/ts/latest/guide/hierarchical-dependency-injection.html

希望它能帮助你,Thierry