NoU*_*ame 14 angularjs angular-ui-router ng-upgrade angular
在使用ng-upgrade在大型ng1(V1.5.9)应用程序(使用ui-router)中使用一些新的ng2(V2.2.4)组件的应用程序中,我目前看到一个非常奇怪的变化检测问题.据我所知,这已经在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);
}
}
Run Code Online (Sandbox Code Playgroud)
该组件在升级适配器中升级,并在模块中注册为入口组件.
该组件用于ng1控制器的模板,如下所示:
<my-ng2-demo></my-ng2-demo>
Run Code Online (Sandbox Code Playgroud)
当我打开浏览器并直接导航到该页面(ng1控制器的路径)时,一切都按预期工作:ui每2秒显示一次真/假.
然而:当我离开然后回到页面(访问一些不同的路线)然后突然改变检测似乎不起作用.显示的值仅交替大约每5-6秒,看起来很随机,虽然在控制台中我仍然看到预期的值.
当我将组件的构造函数更改为:
constructor(private zone: NgZone) {
this.interval = setInterval(() => {
zone.run(() => {
this.status = !this.status;
console.log('status: ' + this.status);
});
}, 2000);
}
Run Code Online (Sandbox Code Playgroud)
它突然再次起作用.
显然这不是一个可行的解决方案,因为我在真实应用程序中看到的行为要复杂得多(我可能需要zone.run在几十个地方添加,这是不可维护的).
我已经调试了几个小时,不明白发生了什么.在Chrome的JavaScript分析器中,我基本上看到该页面在5-6秒内几乎整天都没有发生任何事情.
这不是该演示组件的屏幕截图(但它看起来基本相同),但是从我最初测试的标签组件进行剖析(标签切换时间也很长,中间没有可见的操作).
更新:
经过一些实验后,我发现相当令人惊讶的是,当我不再将状态改变代码放入zone.run呼叫中时,我添加了一个调用ApplicationRef.tick()
(如此处所述:https://stackoverflow.com/a/34829089/ 1335619)它也根本不起作用.我不明白为什么强制完整的应用程序更改检测什么都不做,但区域运行调用以某种方式工作.
带有勾号调用的示例代码不起作用:
constructor(private applicationRef:ApplicationRef) {
this.interval = setInterval(() => {
this.status = !this.status;
console.log('status: ' + this.status);
applicationRef.tick();
}, 2000);
}
Run Code Online (Sandbox Code Playgroud)
小智 4
您使用的 Angular 版本存在错误。更改检测在 ng 升级的应用程序中无法正常工作。
请参阅https://github.com/angular/angular/issues/12318了解更多详细信息。
如果升级到 2.4.4,应该可以解决该问题。