有角度的区域

问题描述 投票:6回答:2
  1. 什么是区域?
  2. 角度ngZone与zone.js有何不同?
  3. 什么时候应该使用它们?有人可以帮助使用ngZone的实际例子吗?

我在这里经历了角度文档但是,我无法完全理解。

https://angular.io/api/core/NgZone

angular zone.js
2个回答
19
投票

NgZone是Zone.js的包装器,它是一个库,它创建一个围绕异步函数的上下文,以使它们可跟踪。

角度变化检测严重依赖于Zones,如何?

Angular需要一种了解何时运行更改检测的方法,这基本上只是更新DOM以表示最新的模型(javascript)更改。

想象一下,我们有一个例子:

  <div id="content"></div>

在我们的javascript代码中,我们有

const element = document.getElementById('content');

function updateText(){
     element.innerHtml = myText+ ": updated at time"+Date.now()
}

让我们说最初我要用hello更新content

  const myText = "Hello";

  this.updateText();

这会将我的HTML内容更新为文本:“Hello在19:30更新”

然后让我们说我想在用户点击后将myText变量更新为其他变量:

  <button onClick="updateTheTextAgain()"></button>



  updateTheTextAgain(){

     this.myText = "Hi there";
  }

如果我点击那个按钮会发生什么?

没有;

好吧,实际上,它不是,“没什么”,我设法更新变量,但我没有更新视图(我没有检测到模型的变化),所以我需要调整我的updateTheTextAgain为:

   updateTheTextAgain(){

     this.myText = "Hi there";
       this.updateText(); /// Making sure I'm detecting the change ( I'm updating the `DOM`)

  }

现在,单击按钮将更新我的视图(因为手动更改检测)。

这显然不是最好的主意,因为那时我必须编写很多updateText函数,并在我更新模型之后将它们调用到我希望更新的任何地方,对(回到Angular1并记住$scope.apply())?

这里是ZoneJs令人惊叹的地方。

想象一下,如果我可以重写onClick函数,我的意思是浏览器的原始onClick函数是:

 const originalOnClick = window.onClick;


 window.onClick = function(){
    originalOnClick();
    this. updateText();
 }

这被称为本地函数的monkey patchingopen heart surgery

我到底得到了什么?

在我将patched onClick放入页面之后,所有将在整个应用程序中编写的onClick函数将通过我的patched onClick,这意味着,我不必在每次onclick之后运行updateText()函数,因为它被纳入click事件处理程序本身。

在Angular中,updateTextchange detection,Angular在所有原生事件中都有钩子(通过使用Zones)。

所以当你写:

   setTimeout(()=>{
        console.log('Do something');

   },100);

你实际写的是这样的:

   setTimeout(()=>{
        console.log('Do something');
        runAngularsChangeDetection(); 
   },100);

上面是远离实际发生的事情,但它是变化检测和Zones的整个故事的核心,为什么我们需要它们/

**更新:**

我们什么时候应该使用NgZone

当你想使用NgZone时会有很多情况,我可以说出两个:

1-当你想要在Angular变化检测之外运行时:

还记得我说Angular在所有异步事件中都有钩子吗? window.onScroll就是其中之一,现在假设我们想在用户滚动时做一些计算,你通常做的是:

   window.onscroll = ()=>{

    // do some heavy calculation : 
  }     

现在,在滚动时,您的函数正如您所期望的那样正常调用,但您可能会注意到您遇到了一些性能问题,这可能是因为Angular在每个滚动事件(预期行为)上运行changeDetection

如果你的组件中有很多绑定,那么你肯定会注意到滚动上的性能下降。

所以有一种方式就是说,嘿Angular,忽略我的onscroll事件,我知道我在做什么,我不想让你运行变化检测,在这种情况下,你会使用NgZone

 constructor(private zone:NgZone){
   this.zone.runOutsideOfAngular(()=>{
      window.onscroll = ()=>{
       // do some heavy calculation : 
      }
    })
  }

这将确保Angular不会在滚动时运行更改检测。

另一个案例与上面完全相反,你有一个函数在某种程度上在Angular的区域之外,你希望它在里面,就像第三方库为你做一些东西而你希望它被绑定到你的角度周期。

   this.zone.run(()=>{
        $.get('someUrl').then(()=>{
           this.myViewVariable = "updated";
        })
   });

不使用Zone,您很可能需要这样做:

         $.get('someUrl').then(()=>{
           this.myViewVariable = "updated";
           this.changeDetectorRef.detectChanges();
        })

但请注意,当你的函数在区域内(run方法)时,你不必自己手动调用detectChanges而angular会完成这项工作


1
投票

目前的官方文件不符合标准。有人在Angular做疯狂的东西,Pascal Precht也是如此。他的下面的文章将帮助您了解什么是ZonengZone

https://blog.thoughtram.io/angular/2016/02/01/zones-in-angular-2.html

© www.soinside.com 2019 - 2024. All rights reserved.