我正在使用Angular 7并遇到问题=>登录成功后,API GET调用成功,并且组件也接收数据,但是UI未显示该数据。
当我打开浏览器控制台时,立即将数据填充到UI上,并在控制台中显示警告。
“ core.js:15686导航在Angular区域之外触发,您忘了调用'ngZone.run()'吗?”
我已经搜索了此警告,并找到了诸如this.ngZone.run()
之类的解决方法,并在其中调用了我的API。
但是问题是,我正在使用40多个组件,并且在每个组件中调用了许多API。因此,我必须在每次API调用时都调用ngZone.run()
,这似乎很难做到。
请向我建议克服此问题的更好方法。 预先感谢。
app.component.ts
getEmployees(): void {
this.employeeService.getEmployees().subscribe(e => {
this.employees = e;
});
}
app.service.ts
@Injectable()
export class EmployeeService {
constructor(private httpClient: HttpClient) { }
getEmployees() {
return this.httpClient.get<EmployeeModel[]>('employees');
}
答案 0 :(得分:10)
我的问题通过将路由器导航命令包装在ngZone中得以解决。请检查下面的代码
在构造函数中添加“私有区域:NgZone”。
private zone: NgZone
this.zone.run(() => {
this.router.navigate(['/login']);
});
答案 1 :(得分:7)
通常,当您将角度调用包装在与外部Java无关的外部JavaScript回调中时,就会发生这种情况。
示例app.component.ts
:
callMyCustomJsLibrary() {
googleSdk.getLocations(location => this.getEmployees());
}
getEmployees(): void {
this.employeeService.getEmployees().subscribe(e => {
this.employees = e;
});
}
在这种情况下,您必须将呼叫包括在NgZone中,例如:
this.ngZone.run(() => this.getEmployees());
app.component.ts
如下所示:
callMyCustomJsLibrary() {
googleSdk.getLocations(location => {
this.ngZone.run(() => this.getEmployees()); // now wrapped inside ngZone
});
}
getEmployees(): void {
this.employeeService.getEmployees().subscribe(e => {
this.employees = e;
});
}
答案 2 :(得分:5)
我遇到了同样的问题。这对我有用,你有两种方法:
第一种形式:
document.location.href=`/component/${param}/...`
这样做的问题是它会重新加载整个应用程序,这会使它变慢
第二种方法:
导入这个
import { Router } from '@angular/router';
import { Component, NgZone } from '@angular/core';
构造函数:
constructor(private _ngZone: NgZone, private _router: Router) { }
goTo(comp, param){
this._ngZone.run(()=>{
this._router.navigate([comp, param])
});
}
所以当你想访问你的组件时,只需:
this.goTo("/myComponent", "my-param-value");
希望对你有用
答案 3 :(得分:2)
如果我从头开始讲话,则此警告的含义是事件是在区域之外触发的,即如果您知道区域或也称为执行上下文,哪个角度是用于更改检测和UI呈现。因此,在进行导航时,角度会期望它重新呈现UI,但是在这里不会发生,这就是您面临的问题。之所以会发出此警告,是因为执行代码时角度处理更改检测和UI呈现位于角度区域内。
但是实际上,当您尝试在 subscribe 方法中调用路由器导航时,会出现此警告。
将您的路由器导航调用置于subscribe方法之外,它不会再次引发此警告。并在导航后看到预期的UI。
有关区域的更多信息,请阅读并观看下面的视频:-
答案 4 :(得分:1)
如果您尝试注入定制服务,就会发生这种情况:
constructor(private myService: MyService) {
}
您忘记在模块配置中提供它:
@NgModule({
providers: [
MyService
]
答案 5 :(得分:0)
工作解决方案 - 修复
ngAfterViewInit(): void {
let self = this;
this.platform.backButton.subscribe(() => {
console.log("back preseed \n \n");
self._ngZone.runOutsideAngular(() => {
setTimeout(() => {
self.Router.navigateByUrl("/stock-management");
}, 100);
});
});
}