Angularjs 通过angular1 ui路由器导航后,ng2组件中的更改检测无法正常工作

Angularjs 通过angular1 ui路由器导航后,ng2组件中的更改检测无法正常工作,angularjs,angular,angular-ui-router,ng-upgrade,Angularjs,Angular,Angular Ui Router,Ng Upgrade,在一个使用ng升级的应用程序中,在一个大型ng1(V1.5.9)应用程序(使用ui路由器)中使用一些新的ng2(V2.2.4)组件,我目前看到一个非常奇怪的更改检测问题。据我所知,这已经在ng2的一些升级中引入,但遗憾的是,目前我无法轻松验证这一点 到目前为止,我已将其简化为一个简单的示例,其中我只使用了以下组件: @Component({ selector:'my-ng2-demo', template: '<div>{{status}}</div>'

在一个使用ng升级的应用程序中,在一个大型ng1(V1.5.9)应用程序(使用ui路由器)中使用一些新的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);
    }

}
它突然又起作用了

显然,这不是一个可行的解决方案,因为我在实际应用程序中看到的行为要复杂得多(我必须添加
zone.run
,可能在几十个地方运行,这是不可维护的)

我已经调试了几个小时了,不知道发生了什么。 在Chrome的JavaScript分析器中,我基本上看到页面在5-6秒内几乎整个时间都处于空闲状态,没有任何事情发生

这不是演示组件的截图(但基本上看起来是一样的),而是我最初测试的标签组件(标签切换所用的时间同样长,其间没有可见的操作)

更新:

经过更多的实验后,我发现非常令人惊讶的是,当不将状态更改代码放入
区域.run
调用时,我添加了对
ApplicationRef.tick()的调用

(如本文所述,例如:)它也根本不起作用。
我不明白为什么强制执行一个完整的应用程序更改检测什么都不起作用,但区域运行调用却能以某种方式工作

打勾调用不起作用的示例代码:

constructor(private applicationRef:ApplicationRef) {
    this.interval = setInterval(() => {
        this.status = !this.status;
        console.log('status: ' + this.status);
        applicationRef.tick();
    }, 2000);
}

您正在使用的Angular版本中有一个bug。在ng升级的应用程序中,更改检测无法正常工作

有关详细信息,请参阅


如果升级到2.4.4,应该可以解决这个问题。

您有没有一个简单的例子来重现它?可能是plunker或github repo?还没有,但如果您知道一个plunker已经有了基本的angular1+angular2+ngUpgrade+ui路由器设置,我很乐意将其应用到我的示例中。请检查您在任何组件中都没有以下标志:封装:ViewEncapsulation.None,并尝试将逻辑从构造函数移动到ngOnInit()。我们确实有封装:ViewEncapsulation。一个组件中没有一个组件,但它是一个甚至没有在每个UI上使用的组件,您是否仍然认为它会导致它?对我来说,仍然存在漏洞,版本4.1.1
constructor(private zone: NgZone) {
    this.interval = setInterval(() => {
        zone.run(() => {
            this.status = !this.status;
            console.log('status: ' + this.status);
        });
    }, 2000);
}
constructor(private applicationRef:ApplicationRef) {
    this.interval = setInterval(() => {
        this.status = !this.status;
        console.log('status: ' + this.status);
        applicationRef.tick();
    }, 2000);
}