如何处理 Angular 7 中的连接丢失页面?
How to handle connection loss page in Angular 7?
我想要的是,如果网络不可用,并且用户尝试导航到下一页 ConnectionLost
组件将在那里。
但如果没有网络,用户不采取任何操作,则意味着不会导航到第二页。那么不应该有一个连接丢失的页面。用户应该停留在当前页面。
为此,我实现了 canActivate 守卫,代码如下:
@Injectable({
providedIn: 'root'
})
export class NetworkGuard implements CanActivate {
constructor(private router: Router, private network: NetworkService) {
}
canActivate(next: ActivatedRouteSnapshot,
state: RouterStateSnapshot): Observable<boolean | UrlTree> | Promise<boolean | UrlTree> | boolean | UrlTree {
if (window.navigator.onLine) {
return true;
} else {
if (!this.isConnectionLostComponent()) {
this.router.navigate(['/connection-lost'], {skipLocationChange: true});
}
return false;
}
}
private isConnectionLostComponent() {
// check whether connection lost component is added on not
return this.network.isActive;
}
}
除一种情况外,它工作正常。
也就是说,如果我从浏览器中单击后退或前进,它会将 URL connection-lost
更新到 地址栏
我该如何解决这个问题?
可以看样例Here
产生问题的步骤:
- 单击横幅(按钮)-> URL 更改为“/横幅”
- 单击品牌(按钮)-> URL 更改为“/品牌”
- 在该品牌页面上断开网络连接
- 从浏览器单击返回-> ConnectionLostComponent 并且 url 是 '/brand',没关系
- 再次单击返回 -> ConnectionLostComponent 但 url 也更改为“/connection-lost”。这就是我面临的问题。
我只是不想用'/connection-lost'更新URL,为此我在[=16=中的router.navigate
方法中添加了skipLocationChange: true
选项], 但是还是不行
我不知道它是否适合您,但我在我的项目中所做的如下。
app.component.ts
constructor(){
this.onlineOffline = Observable.merge(of(navigator.onLine),
fromEvent(window, 'online').pipe(map(() => true)),
fromEvent(window, 'offline').pipe(map(() => false))
);
}
app.component.html
<ng-container *ngIf="onlineOffline | async; then thenTemplate; else elseTemplate"></ng-container>
<ng-template #thenTemplate>
<router-outlet></router-outlet>
</ng-template>
<ng-template #elseTemplate>
<app-no-network></app-no-network>
</ng-template>
让我知道它是否按照您需要的方式工作。
经过一些搜索,并在@AlokeT 的回答的帮助下。我找到了这个问题的解决方案。
@AlokeT 的建议是在用户丢失 his/her 网络后立即显示连接丢失页面。但我的要求是在 he/she 尝试导航到另一个页面时显示连接丢失页面。
在这个回答中,我刚刚补充了缺失的部分。
为此,我只是更新了 Guard 的 isNetworkStopped
标志,因为每个 CanActivate 守卫都在导航开始之前执行。因此,当用户更改路径时,会显示连接丢失组件。
我在 NetworkGuard 中使用了 NetworkService
代码,
@Injectable({providedIn: 'root'})
export class NetworkService {
online: boolean;
isNetworkStopped = false;
constructor() {
this.online = window.navigator.onLine;
fromEvent(window, 'online').subscribe(e => {
this.online = true;
});
fromEvent(window, 'offline').subscribe(e => {
this.online = false;
});
}
}
在上面的代码中我只是添加了一个标志isNetworkStopped
。并从 NetworkGuard
更新了该标志,这意味着当用户尝试导航到下一页时发现没有网络。
并且还从 NetworkGuard 中删除了导航。
请参阅下面的 NetoworkGuard
更新代码
@Injectable({providedIn: 'root'})
export class NetworkGuard implements CanActivate {
constructor(private network: NetworkService) {
}
canActivate(next: ActivatedRouteSnapshot,
state: RouterStateSnapshot): Observable<boolean | UrlTree> | Promise<boolean | UrlTree> | boolean | UrlTree {
if (this.network.online) {
return true;
}
this.network.isNetworkStopped = true;
return false;
}
}
基于该标志,我设法显示了 ConnectionLost 组件。
为此,ConnectionLost
组件是根据根组件模板的条件添加的。
app.component.html
<router-outlet *ngIf="!networkService.isNetworkStopped"></router-outlet>
<app-connection *ngIf="networkService.isNetworkStopped"></app-connection>
并且来自 ConnectionLost 组件,如果用户单击重新加载按钮。通过检查网络连接,我更新了 NetworkService
的 isNetworkStopped
标志。
我想要的是,如果网络不可用,并且用户尝试导航到下一页 ConnectionLost
组件将在那里。
但如果没有网络,用户不采取任何操作,则意味着不会导航到第二页。那么不应该有一个连接丢失的页面。用户应该停留在当前页面。
为此,我实现了 canActivate 守卫,代码如下:
@Injectable({
providedIn: 'root'
})
export class NetworkGuard implements CanActivate {
constructor(private router: Router, private network: NetworkService) {
}
canActivate(next: ActivatedRouteSnapshot,
state: RouterStateSnapshot): Observable<boolean | UrlTree> | Promise<boolean | UrlTree> | boolean | UrlTree {
if (window.navigator.onLine) {
return true;
} else {
if (!this.isConnectionLostComponent()) {
this.router.navigate(['/connection-lost'], {skipLocationChange: true});
}
return false;
}
}
private isConnectionLostComponent() {
// check whether connection lost component is added on not
return this.network.isActive;
}
}
除一种情况外,它工作正常。
也就是说,如果我从浏览器中单击后退或前进,它会将 URL connection-lost
更新到 地址栏
我该如何解决这个问题? 可以看样例Here
产生问题的步骤:
- 单击横幅(按钮)-> URL 更改为“/横幅”
- 单击品牌(按钮)-> URL 更改为“/品牌”
- 在该品牌页面上断开网络连接
- 从浏览器单击返回-> ConnectionLostComponent 并且 url 是 '/brand',没关系
- 再次单击返回 -> ConnectionLostComponent 但 url 也更改为“/connection-lost”。这就是我面临的问题。
我只是不想用'/connection-lost'更新URL,为此我在[=16=中的router.navigate
方法中添加了skipLocationChange: true
选项], 但是还是不行
我不知道它是否适合您,但我在我的项目中所做的如下。
app.component.ts
constructor(){
this.onlineOffline = Observable.merge(of(navigator.onLine),
fromEvent(window, 'online').pipe(map(() => true)),
fromEvent(window, 'offline').pipe(map(() => false))
);
}
app.component.html
<ng-container *ngIf="onlineOffline | async; then thenTemplate; else elseTemplate"></ng-container>
<ng-template #thenTemplate>
<router-outlet></router-outlet>
</ng-template>
<ng-template #elseTemplate>
<app-no-network></app-no-network>
</ng-template>
让我知道它是否按照您需要的方式工作。
经过一些搜索,并在@AlokeT 的回答的帮助下。我找到了这个问题的解决方案。
@AlokeT 的建议是在用户丢失 his/her 网络后立即显示连接丢失页面。但我的要求是在 he/she 尝试导航到另一个页面时显示连接丢失页面。
在这个回答中,我刚刚补充了缺失的部分。
为此,我只是更新了 Guard 的 isNetworkStopped
标志,因为每个 CanActivate 守卫都在导航开始之前执行。因此,当用户更改路径时,会显示连接丢失组件。
我在 NetworkGuard 中使用了 NetworkService
代码,
@Injectable({providedIn: 'root'})
export class NetworkService {
online: boolean;
isNetworkStopped = false;
constructor() {
this.online = window.navigator.onLine;
fromEvent(window, 'online').subscribe(e => {
this.online = true;
});
fromEvent(window, 'offline').subscribe(e => {
this.online = false;
});
}
}
在上面的代码中我只是添加了一个标志isNetworkStopped
。并从 NetworkGuard
更新了该标志,这意味着当用户尝试导航到下一页时发现没有网络。
并且还从 NetworkGuard 中删除了导航。
请参阅下面的 NetoworkGuard
@Injectable({providedIn: 'root'})
export class NetworkGuard implements CanActivate {
constructor(private network: NetworkService) {
}
canActivate(next: ActivatedRouteSnapshot,
state: RouterStateSnapshot): Observable<boolean | UrlTree> | Promise<boolean | UrlTree> | boolean | UrlTree {
if (this.network.online) {
return true;
}
this.network.isNetworkStopped = true;
return false;
}
}
基于该标志,我设法显示了 ConnectionLost 组件。
为此,ConnectionLost
组件是根据根组件模板的条件添加的。
app.component.html
<router-outlet *ngIf="!networkService.isNetworkStopped"></router-outlet>
<app-connection *ngIf="networkService.isNetworkStopped"></app-connection>
并且来自 ConnectionLost 组件,如果用户单击重新加载按钮。通过检查网络连接,我更新了 NetworkService
的 isNetworkStopped
标志。