angular9 - 如何解决 Ionic 中的区域感知承诺
问题描述
我正在使用带有电容器版本 2.2.0 的 ionic5。我正在使用电容器网络来检测网络是在线还是离线。但是 Network.getStatus() 返回“区域感知承诺”。以下是我尝试过的代码。
网络服务
import { Injectable, OnDestroy } from '@angular/core';
//import { Network } from '@ionic-native/network/ngx';
import { ErrorNotificationService } from '../service/error-notification.service';
import { errorMessages } from '../service/dao/errorMessageConstants';
import { TranslateConfigService } from './translate-config.service';
import { Plugins,NetworkStatus, PluginListenerHandle } from '@capacitor/core';
const { Network } = Plugins;
@Injectable({
providedIn: 'root'
})
export class NetworkService {
networkStatus: NetworkStatus;
networkListener: PluginListenerHandle;
constructor(private errorService:ErrorNotificationService) {
this.listenToInternet();
}
listenToInternet(){
this.networkListener = Network.addListener('networkStatusChange', (status) => {
console.log("Network status changed", status);
if(status && !status.connected){
this.errorService.showTextErrorAlert(this.translateService.getTranslatedValue("messages.no_connection"))
}
this.networkStatus = status;
});
}
checkNetworkPresent(){
return Network.getStatus().then(network =>{
console.log(network,"network as service")
return network;
})
}
}
由于电容器插件返回承诺,我正在使用“then”,它在我获得网络状态后执行。我在下面的拦截器中调用此方法,但我得到“区域感知承诺”。
Http 拦截器
import { Injectable } from '@angular/core';
import { HttpRequest, HttpHandler, HttpInterceptor, HttpErrorResponse } from '@angular/common/http';
import { NetworkService } from './network.service'
import { NEVER, throwError } from 'rxjs';
import { LoaderService } from './loader.service'
import { ErrorNotificationService } from '../service/error-notification.service'
@Injectable({
providedIn: 'root'
})
export class HttpInterceptorsService implements HttpInterceptor {
networkStatus : any;
constructor(private networkService:NetworkService,private loader:LoaderService,private errorService:ErrorNotificationService) {}
intercept(req: HttpRequest<any>, next: HttpHandler) {
//here checknetworkPresent returns zone aware promise
this.networkStatus = this.networkService.checkNetworkPresent();
console.log(this.networkStatus,"Network")
if(!this.networkStatus["connected"]){
this.loader.hideLoader();
// this.errorService.showTextErrorAlert("No Internet Connection")
return throwError("no_connection");
}else{
return next.handle(req);
}
}
}
我在某个地方出错了吗?
解决方案
当我们要求 Angular 执行一些“Angular Zone”之外的事件/任务时,就会产生区域感知问题,所有这些都是为了确保我们可以完全控制应用程序。
NgZone 本身就是一个非常复杂的东西,一开始就很难理解。我建议你看看这个。您可以在 Javascript 中创建自己的区域。
回到你的问题。
所以目前这里发生的是对 networkStatus 插件的调用被阻止,因为它是在 NgZone 之外执行的。
为了解决您的问题,您需要:
- 在您的 NetworkService 中注入 ngZone。
- 根据您的用例包装您的代码
run()
或方法。runTask()
所以你需要做这样的事情:
@Injectable({
providedIn: 'root'
})
export class NetworkService {
networkStatus: NetworkStatus;
networkListener: PluginListenerHandle;
constructor(
private errorService:ErrorNotificationService,
private ngZone: NgZone // <~ 1. Inject ngZone
) {
this.listenToInternet();
}
listenToInternet(){
this.networkListener = Network.addListener('networkStatusChange', (status) => {
console.log("Network status changed", status);
if(status && !status.connected){
this.errorService.showTextErrorAlert(this.translateService.getTranslatedValue("messages.no_connection"))
}
this.networkStatus = status;
});
}
checkNetworkPresent(){
// 2. Wrap your code with `run` or `runTask` depending on your usecase
this.ngZone.runTask(() => {
return Network.getStatus().then(network =>{
console.log(network,"network as service")
return network;
});
});
}
}
我希望这可以帮助你。
快乐编码。
推荐阅读
- hyperledger-fabric - 超级账本结构先前的哈希知道
- java - 无法在 Spring Boot 应用程序中设置 hystrix 仪表板
- nginx - 使用自定义日志格式时,nginx 变量为空
- elixir - 使用管道运算符检查布尔条件?
- angular - Angular,错误 TS2339:“响应”类型上不存在属性“任务”
- posix - POSIX:perror() - “MT-Safe race:stderr”是什么意思?
- node.js - Express.js CRUD 应用程序无法删除
- php - 如何删除超大字符串php中的最后一个字符
- google-sheets - 为什么这个 IMPORTXML 公式显示错误?
- excel - Excel VBA 对于每个带有数据验证列表的循环