通过angular1 ui-router

时间:2016-12-22 08:26:35

标签: angularjs angular angular-ui-router ng-upgrade

在使用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);
    }

}

该组件在升级适配器中升级,并在模块中注册为入口组件。

该组件在ng1控制器的模板中使用,如下所示:

<my-ng2-demo></my-ng2-demo>

当我打开浏览器并直接导航到该页面(ng1控制器的路径)时,一切都按预期工作:ui每2秒显示一次真/假。

然而:当我离开&amp;然后回到页面(访问一些不同的路线)然后突然改变检测似乎没有工作。显示的值仅交替大约每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秒内几乎整个时间都没有空闲。

profiler 这不是该演示组件的截图(但它看起来基本相同),但是从我最初测试的标签组件进行分析(标签切换时间也很长,中间没有可见的操作)。

更新

经过一些实验后,我发现非常令人惊讶的是,我不是将状态更改代码放入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);
}

1 个答案:

答案 0 :(得分:3)

您正在使用的Angular版本中存在错误。变更检测在ng-upgrade应用程序中不起作用。

有关详细信息,请参阅https://github.com/angular/angular/issues/12318

如果升级到2.4.4,则应解决此问题。