我的棱角项目中有一个错误,该错误最终通过将代码包装到
中而得以解决this.zone.run(() => {/* my code here */});
如this答案所述。
我以前对zone
的理解是angular无法检测到异步callbacks
对第三方库的更改,因为“它们不在angular的zone
中”。如果我点击button
,则触发的事件不是浏览器的本机click
事件,而是由angular创建的自定义(修补)click
事件,其handler
在zone
,以便angular知道其回调处理程序所做的更改。
但是我无法理解在第三方回调中运行router.navigate()
会导致此问题(如this github问题所指出)。 Router
是否不是角度本身的service
?为什么在第三方zone
中调用时,它不会自动通知angular的callback
?
我在NGXS的状态缩减器中使用router.navigate
遇到了这个问题。
我的问题是:
有人可以解释我究竟何时需要将代码包装在NgZone
中?
调试数小时并意识到我的代码不在zone
上下文之内。
答案 0 :(得分:1)
ngZone.runOutsideAngular()-这会在角度区域之外运行代码。
Angular本身使用引擎盖下的ngZone来检测更改
因此,如果我们走出了角度区域,那么要返回,我们使用ngZone.run()
答案 1 :(得分:0)
您是否使用BrowserAnimationsModule?
我不得不将某些路由器重定向包装在zone.run()中,这也存在相同的问题,这可能是由于以下打开的错误所致:
答案 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事件(
click
,keydown
,keyup
,etc
,setTimeout
,setInterval
。XMLHttpRequest
NgZone只是围绕Zone.js
的API的包装角度服务。
Angular团队决定在使用Angular时需要执行上下文的抽象,因此他们在Angular中构建了Zone.js和一个包装器(非正式地称为适配器模式)。
所以基本上可以回答您的问题:在Zone.js中处理任何与Angular运行上下文无关的第三方库时(除非您确定不需要执行上下文,并且可以使用{{3} }使用NoopNgZone
)