Angular2 组件视图持续更新
Angular2 component view updated continuously
我有一个 Angular 2 组件,它显示项目列表,并注册到发布事件的服务。问题是,即使我在收到事件时不做任何事情,Angular 也会更新视图(或者至少在我认为不应该做的时候做一些事情)。
正如您在控制台中看到的,每次我的服务发布消息时,我的项目的 "getTitle()" 方法都会被调用。
即使我没有注册到我的服务并且如果我的组件没有实现 MyServiceListener 接口,每次服务收到消息时都会调用 getTitle。如果我不在其构造函数中为我的组件提供服务,那么一切都很好。所以,我的依赖注入似乎有问题,但是什么?
这里是plunker的相关代码:
我的服务及其侦听器接口:
export interface MyServiceListener {
onMessage(_message: any);
}
export class MyService {
private m_listener: MyServiceListener;
constructor() {
window.setInterval(() => {
if (this.m_listener !== undefined) {
this.m_listener.onMessage("Hi");
}
}, 500);
}
setListener(_listener: MyServiceListener) { this.m_listener = _listener; }
}
项目class:
export class Item {
m_title: string;
constructor(_title: string) {
this.m_title = _title;
}
getTitle(): string { console.log("getTitle"); return this.m_title; }
}
我的组件:
@Component({
selector: 'my-app',
template : `
<div>
<ul>
<li *ng-for="#item of m_items">
{{item.getTitle()}}
</li>
</ul>
</div>
`
})
export class App implements TestBugAngularServiceListener {
private m_items: Array<Item> = new Array<Item>();
constructor(_communicationService: MyService) {
this.m_items.push(new Item("A"));
this.m_items.push(new Item("B"));
this.m_items.push(new Item("C"));
_communicationService.setListener(this);
}
onMessage(_message: any) {
}
}
bootstrap(App, [MyService]).catch(err => console.error(err));
这两篇文章:Change detection and Angular immutability解释了很多关于Angular 2如何检测对象的变化,以及如何遍历angular 2中的组件树来执行数据绑定的事情...
在你的示例中,我认为你的组件 "my-app" 可以被认为是 "Immutable",因此将其 "change detection strategy" 更改为 OnPush 可以解决你的问题。
你可以这么写:
@Component({
selector: 'my-app',
changeDetection: ChangeDetectionStrategy.OnPush,
template : `
<div>
<ul>
<li *ng-for="#item of m_items">
{{item.getTitle()}}
</li>
</ul>
</div>
`
})
并且在将导入添加到 ChangeDetectionStrategy 之后,"my-app" 的数据绑定将不会在每个浏览器事件之后计算,而只会在其输入发生变化时计算,所以永远不会...
我有一个 Angular 2 组件,它显示项目列表,并注册到发布事件的服务。问题是,即使我在收到事件时不做任何事情,Angular 也会更新视图(或者至少在我认为不应该做的时候做一些事情)。
正如您在控制台中看到的,每次我的服务发布消息时,我的项目的 "getTitle()" 方法都会被调用。
即使我没有注册到我的服务并且如果我的组件没有实现 MyServiceListener 接口,每次服务收到消息时都会调用 getTitle。如果我不在其构造函数中为我的组件提供服务,那么一切都很好。所以,我的依赖注入似乎有问题,但是什么?
这里是plunker的相关代码:
我的服务及其侦听器接口:
export interface MyServiceListener {
onMessage(_message: any);
}
export class MyService {
private m_listener: MyServiceListener;
constructor() {
window.setInterval(() => {
if (this.m_listener !== undefined) {
this.m_listener.onMessage("Hi");
}
}, 500);
}
setListener(_listener: MyServiceListener) { this.m_listener = _listener; }
}
项目class:
export class Item {
m_title: string;
constructor(_title: string) {
this.m_title = _title;
}
getTitle(): string { console.log("getTitle"); return this.m_title; }
}
我的组件:
@Component({
selector: 'my-app',
template : `
<div>
<ul>
<li *ng-for="#item of m_items">
{{item.getTitle()}}
</li>
</ul>
</div>
`
})
export class App implements TestBugAngularServiceListener {
private m_items: Array<Item> = new Array<Item>();
constructor(_communicationService: MyService) {
this.m_items.push(new Item("A"));
this.m_items.push(new Item("B"));
this.m_items.push(new Item("C"));
_communicationService.setListener(this);
}
onMessage(_message: any) {
}
}
bootstrap(App, [MyService]).catch(err => console.error(err));
这两篇文章:Change detection and Angular immutability解释了很多关于Angular 2如何检测对象的变化,以及如何遍历angular 2中的组件树来执行数据绑定的事情...
在你的示例中,我认为你的组件 "my-app" 可以被认为是 "Immutable",因此将其 "change detection strategy" 更改为 OnPush 可以解决你的问题。
你可以这么写:
@Component({
selector: 'my-app',
changeDetection: ChangeDetectionStrategy.OnPush,
template : `
<div>
<ul>
<li *ng-for="#item of m_items">
{{item.getTitle()}}
</li>
</ul>
</div>
`
})
并且在将导入添加到 ChangeDetectionStrategy 之后,"my-app" 的数据绑定将不会在每个浏览器事件之后计算,而只会在其输入发生变化时计算,所以永远不会...