何时使用Ngzone.run()?

时间:2018-07-21 11:22:26

标签: angular ngzone

我的棱角项目中有一个错误,该错误最终通过将代码包装到

中而得以解决
this.zone.run(() => {/* my code here */});

this答案所述。

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

但是我无法理解在第三方回调中运行router.navigate()会导致此问题(如this github问题所指出)。 Router是否不是角度本身的service?为什么在第三方zone中调用时,它不会自动通知angular的callback

我在NGXS的状态缩减器中使用router.navigate遇到了这个问题。

我的问题是:

有人可以解释我究竟何时需要将代码包装在NgZone中?

调试数小时并意识到我的代码不在zone上下文之内。

4 个答案:

答案 0 :(得分:1)

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

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

Angular本身使用引擎盖下的ngZone来检测更改

因此,如果我们走出了角度区域,那么要返回,我们使用ngZone.run()

答案 1 :(得分:0)

您是否使用BrowserAnimationsModule?

我不得不将某些路由器重定向包装在zone.run()中,这也存在相同的问题,这可能是由于以下打开的错误所致:

https://github.com/angular/angular/issues/20290

答案 2 :(得分:0)

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

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

答案 3 :(得分:0)

  

Zone.js是用于跟踪和拦截异步操作的执行上下文   例如:DOM事件(clickkeydownkeyupetcsetTimeoutsetIntervalXMLHttpRequest

NgZone只是围绕Zone.js的API的包装角度服务。

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

所以基本上可以回答您的问题:在Zone.js中处理任何与Angular运行上下文无关的第三方库时(除非您确定不需要执行上下文,并且可以使用{{3} }使用NoopNgZone

without