角度区域

2024-02-22

  1. 什么是区域?
  2. Angular ngZone 与 zone.js 有何不同?
  3. 什么时候应该使用它们?有人可以帮助提供使用 ngZone 的实际示例吗?

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

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


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

Angular 的变化检测很大程度上依赖于Zones, How?

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

想象一下我们有以下示例:

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

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

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

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

假设一开始我要更新content打个招呼:

  const myText = "Hello";

  this.updateText();

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

然后假设我想更新myText用户单击后变量变为其他内容:

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



  updateTheTextAgain(){

     this.myText = "Hi there";
  }

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

Nothing;

好吧,实际上,这不是“什么”,我设法更新了变量,但我没有更新视图(我没有检测到模型的变化),所以我需要调整我的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 patching or open heart surgery本机函数。

我这样做能得到什么?

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

在 Angular 中,updateText is the change detection, Angular 在所有原生事件中都有钩子(通过使用区域)。

所以当你写:

   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自己手动操作,角度会完成这项工作

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

角度区域 的相关文章

随机推荐