使用 angular2更新组件中的变量更改

我的应用程序有一个名称服务,其中包含的名称。

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) {
}
}
88380 次浏览

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

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

参见
组件交互-父母和孩子通过服务进行交流

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

您应该在这里应用 angular1“点规则”并绑定到引用类型。更改 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;
}
}

我认为君特提供的解决方案是最好的。

也就是说,您必须知道 Angular2服务是单例的,它发生在一个注入器树中。这意味着:

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

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

希望能帮到你, 蒂埃里