什么时候使用Ngzone.run()?

das*_*dsa 16 angular ngzone

我在Angular项目中遇到一个错误,该错误最终通过将代码包装到

this.zone.run(() => {/* my code here */});
Run Code Online (Sandbox Code Playgroud)

答案所述。

我以前的理解zone是angular无法检测到异步callbacks第三方库所做的更改,因为“它们不在angular的范围内zone”。如果我单击a button,则触发的事件不是浏览器的本机click事件,而是click由angular创建的自定义(修补)事件,其handlerzoneso angular中的运行会意识到其回调处理程序所做的更改。

但是我无法理解通过router.navigate()在第三方回调中运行来创建此问题(如此 github问题所示)。是不是Router一个service角本身?为什么zone在第三方中调用时,它不会自动通知angular callback

我通过router.navigate在NGXS的状态缩减器中使用来解决此问题。

我的问题是:

有人可以解释我到底什么时候需要包装我的代码NgZone

调试了几个小时,意识到我的代码没有zone上下文,这很烦人。

小智 11

ngZone.runOutsideAngular() - 在角度区域之外运行代码。

  • 当某个事件被触发时,它会告诉 angular 检测变化。
  • 如果您使用 mouseUp() 或 mouseDown() 事件,那么在每次更改时它都会告诉 angular 检测更改。
  • 如果我们不希望这些更改在 angular 运行时发生(这会降低应用程序的性能),我们可以在 angular 区域之外运行它。
  • 与此相反,如果我们非常想获得每一个更新,那么我们可以使用 ngZone.run()。意味着它将正常运行更改检测。

Angular 本身在底层使用 ngZone 来检测变化

所以,如果我们已经离开了角度区域,那么为了回来,我们使用 ngZone.run()


小智 8

ngZone.run() 在对路由进行单元测试时特别有用。

it('should redirect if condition true, fakeAsync(() => {
  router.navigate(['']);
  fixture.ngZone.run(() => {
    component.redirectIfConditionTrue();
  });
  tick();
  expect(location.path()).toBe('/AgentLeadsManager');
}));
Run Code Online (Sandbox Code Playgroud)
  • 来源:这是我唯一一次不得不使用它


Mul*_*ary 6

Zone.js 是一个执行上下文,用于跟踪和拦截异步操作,例如:DOM 事件 ( click, keydown, keyup, etc), setTimeout, setIntervalXMLHttpRequests)

NgZone 只是围绕Zone.jsAPI的包装角服务。

Angular 团队决定他们在 Angular 上工作时需要对执行上下文进行抽象,因此他们在 Angular 中构建了 Zone.js 和一个包装器(非正式地 - 适配器模式)。

所以基本上要回答你的问题:在处理任何类型的第 3 方库时,它与 Zone.js 中的 Angular 的运行上下文无关(除非你决定不需要执行上下文,并且你可以在没有它的情况下工作使用NoopNgZone

来源