在使用ng升级的应用程序中,使用一些大ng1(V1.5.9)应用程序(使用ui-router)中的一些新的ng2(V2.2.4)组件,我目前看到一个非常奇怪的更改检测问题.据我所知,这是在ng2的一些升级中引入的,但可惜的是我现在不能轻易地验证.
原文链接:https://www.f2er.com/angularjs/142610.html现在我已经简化了这个组件:
@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秒交替一次,看起来很随机,尽管在控制台中我仍然看到预期的值.
当我将组件的构造函数更改为:
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秒内,页面几乎整个空闲.
这不是来自该演示组件的屏幕截图(但它基本上看起来一样),但是从分析我最初测试的选项卡组件(选项卡切换花费的时间长短,之间没有可见的操作).
更新:
经过一些更多的实验,我发现相当令人惊讶的是,当不将状态更改代码放入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); }