假设我的service.ts中有import { Component } from "@angular/core";
import { UserService } from '..' // import the service where you stored it.
@Component({
selector: "team",
templateUrl: "../Scripts/components/team/team.component.html"
})
export class TeamComponent implements OnInit {
public users: IUserID[];
constructor(private _userService: UserService) {
}
}
ngOnInit() {
this._getUserData();
}
private _getUserData() {
this._userService.getUserData(userId) // pass the userId here. you can get it from the router params or somewhere else.
.subscribe(response => {
if(response){
this.users = <IUserID>response.json();
}
},
error => console.log(error)) // handle errors the way you like.
}
interface IUserID {
Login: string;
}
超出了角度的上下文。
function noificationHandler()
由第三方调用,noificationHandler()
基本上使用数组并将数组发送给已订阅其服务的组件。
service.ts
noificationHandler()
component.ts
public mySubject: Subject<any> = new Subject();
public myObservable = this.mySubject.asObservable();
constructor() {
this.registry.subscribe("notification.msg",this.noificationHandler.bind(this));
}
noificationHandler(data) {
this.publishUpdate(data)
}
publishUpdate(data) {
this.mySubject.next(data);
}
此时^^^模板未使用新数据更新
由于constructor(private service: myService) {
this.service.myObservable.subscribe(list => {
this.list = list;
});
}
在角度区域之外,因此有角度
"notification.msg"
时,不会运行更改检测。
现在有两种方法可以调用变更检测。
1)将("notification.msg")
包裹在angular的zone.run()
noificationHandler()
2)通过单独要求组件检测更改
this.registry.subscribe("a2mevent.notification.msg", this.ngZone.run(() => this.noificationHandler.bind(this)));
这两个选项都有效! 我的组件结构如下
constructor(private service: myService, private ref: ChangeDetectorRef) {
this.service.myObservable.subscribe(list => {
this.list = list;
this.ref.detectChanges(); // <==== manually invoking change detection
});
}
问题 -
1)detectChanges()是否仅检测其自身组件的更改,还是会对子组件运行更改检测?
2)zone.run()会触发从根到叶子的所有组件的变化检测吗?
在zone.run()和detectChanges()中,我很好奇性能哪个更好?
答案 0 :(得分:26)
ApplicationRef.tick
(与setTimeout()
相同),zone.run()
会导致整个应用程序发生更改检测。此外,在Angular或Angular中添加的事件侦听器(使用视图绑定或@HostBinding()
导致整个应用程序的更改检测。
ChangeDetectorRef.detectChanges
运行特定组件的变更检测(如果适用,则为其后代,例如由于输入绑定)
如果在Angular的区域外运行的某些代码调用Angular的代码并更改状态,则需要显式调用更改检测,因为Angular无法知道状态发生了变化。
如果对状态的更改对于组件是本地的(例如组件字段),则ChangeDetectorRef.detectChanges
或ChangeDetectorRef.markforCheck
更有效。
如果来自外部的呼叫例如导航到不同的路由,这可能会对许多组件产生影响,并且还不清楚整个路由更改何时完成,因为它可能导致异步调用(以及调用回调) 。
在这种情况下,zone.run()
是更好的选择,因为直接和间接调用的代码(如observable和promises的回调)将在Angular的区域内运行,Angular将识别它们并自动调用更改检测。
答案 1 :(得分:6)
两者都完全不同。
NgZone是一个为您的应用提供区域的库,因此您可以将实例运行到多个范围。
ChangeDetection始终从父级到叶级 A&gt; B> C 当你调用detectChanges()时,它也会调用当前组件及其子组件。因此,这是对叶子组件使用OnPush changesdetectionStrategy的最佳方法,因此它们只会在更新输入时检测更改。
此外,ApplicationRef
与ChangeDetector类似;区别在于它将检测从根组件到最后一个子组件的更改。
ChaneDetection和NgZone是最好的组合,总是避免不必要的ChangeDetection