在角度 ui-router 中导航后,更改检测在 ng2 组件中无法正常工作
Change-detection not working properly in ng2 component after navigation via angular1 ui-router
在一个使用 ng-upgrade 的应用程序中,在一个大的 ng1 (V1.5.9) 应用程序中使用一些新的 ng2 (V2.2.4) 组件(使用 ui-router)我目前看到一个非常奇怪的变化检测问题。据我所知,这已经在 ng2 的一些升级中引入,但遗憾的是我目前无法轻易验证。
我现在已经将它简化为一个最小的例子,我只有这个组件:
@Component({
selector:'my-ng2-demo',
template: '<div>{{status}}</div>'
})
export class MyNg2Demo implements OnDestroy {
public status:boolean = true;
private interval:any;
constructor() {
this.interval = setInterval(() => {
this.status = !this.status;
console.log('status: ' + this.status);
}, 2000);
}
ngOnDestroy():void {
clearInterval(this.interval);
}
}
该组件在升级适配器中升级并在模块中注册为入口组件。
该组件在 ng1 控制器的模板中使用如下:
<my-ng2-demo></my-ng2-demo>
当我打开浏览器并直接导航到该页面(ng1 控制器的路由)时,一切都按预期工作:ui 每 2 秒交替显示 true/false。
但是:当我离开然后返回页面(访问一些不同的路线)时,突然更改检测似乎不起作用。显示值大约每 5-6 秒交替一次,似乎 quite 是随机的,尽管在控制台中我仍然看到预期值。
当我将组件的构造函数更改为:
constructor(private zone: NgZone) {
this.interval = setInterval(() => {
zone.run(() => {
this.status = !this.status;
console.log('status: ' + this.status);
});
}, 2000);
}
突然又好了。
显然这不是一个可行的解决方案,因为我在真实应用程序中看到的行为要复杂得多(我可能不得不在许多地方添加 zone.run
,这将无法维护).
我已经调试了几个小时,但不明白发生了什么。
在 Chrome 的 JavaScript 分析器中,我基本上看到页面在 5-6 秒内几乎一直处于空闲状态,没有任何反应。
这不是该演示组件的屏幕截图(但它基本上看起来是一样的),而是来自我最初测试的选项卡组件的概要分析(选项卡切换花费的时间与两者之间没有可见的操作一样长)。
更新:
经过更多的实验后,我发现 qui 令人惊讶的是,当我没有将状态更改代码放入 zone.run
调用时,我添加了对 [=17 的调用=]
(例如此处提到的: )它也根本不起作用。
我不明白为什么强制执行完整的应用程序更改检测没有任何作用,但 zone-运行 调用以某种方式起作用。
带有无效调用的示例代码:
constructor(private applicationRef:ApplicationRef) {
this.interval = setInterval(() => {
this.status = !this.status;
console.log('status: ' + this.status);
applicationRef.tick();
}, 2000);
}
您使用的 Angular 版本存在错误。更改检测在 ng-upgraded 个应用程序中无法正常工作。
详情请参考https://github.com/angular/angular/issues/12318。
如果升级到 2.4.4,应该可以解决问题。
在一个使用 ng-upgrade 的应用程序中,在一个大的 ng1 (V1.5.9) 应用程序中使用一些新的 ng2 (V2.2.4) 组件(使用 ui-router)我目前看到一个非常奇怪的变化检测问题。据我所知,这已经在 ng2 的一些升级中引入,但遗憾的是我目前无法轻易验证。
我现在已经将它简化为一个最小的例子,我只有这个组件:
@Component({
selector:'my-ng2-demo',
template: '<div>{{status}}</div>'
})
export class MyNg2Demo implements OnDestroy {
public status:boolean = true;
private interval:any;
constructor() {
this.interval = setInterval(() => {
this.status = !this.status;
console.log('status: ' + this.status);
}, 2000);
}
ngOnDestroy():void {
clearInterval(this.interval);
}
}
该组件在升级适配器中升级并在模块中注册为入口组件。
该组件在 ng1 控制器的模板中使用如下:
<my-ng2-demo></my-ng2-demo>
当我打开浏览器并直接导航到该页面(ng1 控制器的路由)时,一切都按预期工作:ui 每 2 秒交替显示 true/false。
但是:当我离开然后返回页面(访问一些不同的路线)时,突然更改检测似乎不起作用。显示值大约每 5-6 秒交替一次,似乎 quite 是随机的,尽管在控制台中我仍然看到预期值。
当我将组件的构造函数更改为:
constructor(private zone: NgZone) {
this.interval = setInterval(() => {
zone.run(() => {
this.status = !this.status;
console.log('status: ' + this.status);
});
}, 2000);
}
突然又好了。
显然这不是一个可行的解决方案,因为我在真实应用程序中看到的行为要复杂得多(我可能不得不在许多地方添加 zone.run
,这将无法维护).
我已经调试了几个小时,但不明白发生了什么。 在 Chrome 的 JavaScript 分析器中,我基本上看到页面在 5-6 秒内几乎一直处于空闲状态,没有任何反应。
更新:
经过更多的实验后,我发现 qui 令人惊讶的是,当我没有将状态更改代码放入 zone.run
调用时,我添加了对 [=17 的调用=]
(例如此处提到的:
带有无效调用的示例代码:
constructor(private applicationRef:ApplicationRef) {
this.interval = setInterval(() => {
this.status = !this.status;
console.log('status: ' + this.status);
applicationRef.tick();
}, 2000);
}
您使用的 Angular 版本存在错误。更改检测在 ng-upgraded 个应用程序中无法正常工作。
详情请参考https://github.com/angular/angular/issues/12318。
如果升级到 2.4.4,应该可以解决问题。