Firefox中的Angular2变化检测无限循环

Angular2 change detection infinite loop in Firefox

本文关键字:无限循环 变化检测 Angular2 中的 Firefox      更新时间:2023-09-26

我偶然发现,在Angular2应用中,有一些触发器会导致Firefox中的无限变化检测循环。

我已经在Plunker上复制了一个:http://plnkr.co/edit/VTS89eJkePLrJjuoDzOK

ScrollToFixed插件做一些基本的dom操作并应用一些样式。但是,如果你滚动"Main"部分,然后滚动"Sidebar"部分,你会看到doCheck被无限调用。

我还能够通过触发Google地图中的标记来触发Firefox中的无限循环。

在IE, Safari或Chrome中不会出现无限循环。我不确定这是Angular2还是Firefox的问题,但我找不到问题的根源。

app.ts

import {Component, View, bootstrap, DoCheck} from 'angular2/angular2';

@Component({
    selector: 'my-app'
})
@View({
    templateUrl: 'template.html'
})
export class App implements DoCheck{
  constructor()
    {
        $('#sidebar').scrollToFixed();
    }
    doCheck(){
      console.log('do check')
    }
}
bootstrap(App);

template.html

<div id="main">Main
</div>
<div id="sidebar">Sidebar
<br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br />
Sidebar bottom
</div>

style.css

* {
  box-sizing:border-box;
}
#main {
  float: left;
  width: 66.66667%;
  height:10000px;
}
#sidebar {
  overflow:scroll;
  float: left;
  width: 33.33333%;
  background-color: #f9f8f9;
  height:200px;
}

index . html

<!DOCTYPE html>
<html>
  <head>
    <title>angular2 playground</title>
    <link href="style.css" rel="stylesheet" />
    <script src="https://code.angularjs.org/tools/traceur-runtime.js"></script>
    <script src="https://code.angularjs.org/tools/system.js"></script>
    <script src="https://code.angularjs.org/tools/typescript.js"></script>
    <script src="config.js"></script>
    <script src="https://code.angularjs.org/2.0.0-alpha.44/angular2.min.js"></script>
    <script type="text/javascript" src="//ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script>
<script src="https://rawgit.com/bigspotteddog/ScrollToFixed/master/jquery-scrolltofixed.js"></script>
    <script>
    System.import('app')
      .catch(console.error.bind(console));
  </script>
  </head>
  <body>
    <my-app>
    loading...
  </my-app>
  </body>
</html>

我不确定为什么这只发生在Firefox中,为什么它会产生一个无限循环,但是抛出的错误表明您试图在创建边栏之前应用$('#sidebar').scrollToFixed();。默认情况下,Angular的构造函数中还没有渲染DOM元素。侧栏只有在Angular初始化DOM之后才可用。你可以把你的代码放在ngafterviewit中,它就会工作了。

您可以阅读https://angular.io/guide/lifecycle-hooks获取更多信息

每当在生命周期中使用检查时,应该小心并确认是否不无限期运行(可能会挂起你的应用程序);我遇到过类似的问题(生命周期钩子)ngAfterContentInit()已经解决了