如何处理Angular 7中的连接丢失页面?

Rav*_*vta 7 javascript guard web angular

我想要的是,如果网络不可用,并且用户尝试导航到下一页,那么ConnectionLostComponent就在那里.

但是,如果没有网络,用户不采取任何行动意味着不导航到第二页.那么不应该有一个连接丢失的页面.用户应该留在当前页面上.

为此,我已经实现了canActivate guard作为以下代码:

@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;
  }
}
Run Code Online (Sandbox Code Playgroud)

除了一个条件外它工作正常.也就是说,如果我从浏览器单击后退或前进,它的更新URL connection-lost地址栏

我怎么能解决这个问题?可以在这里看到样品

产生问题的步骤:

  1. 点击横幅(按钮) - >网址更改为'/ banner'
  2. 点击品牌(按钮) - >网址更改为'/品牌'
  3. 断开该品牌页面上的网络连接
  4. 点击浏览器 - > ConnectionLostComponent,url是'/ brand',没关系
  5. 再次单击 - > ConnectionLostComponent,但url也更改为'/ connection-lost'.这就是我面临的问题.

我只是不想用'/ connection-lost'来更新URL,因为我skipLocationChange: truerouter.navigate方法中添加了选项NetworkGuard,但是它仍然没有用.

Alo*_*keT 6

我不知道这对你来说是不是正确的解决方案,但我在项目中所做的是遵循.

app.component.ts

constructor(){
this.onlineOffline = Observable.merge(of(navigator.onLine),
      fromEvent(window, 'online').pipe(map(() => true)),
      fromEvent(window, 'offline').pipe(map(() => false))
    );
}
Run Code Online (Sandbox Code Playgroud)

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>
Run Code Online (Sandbox Code Playgroud)

让我知道它是否按照你需要的方式实现它.

  • 因此,您可以制作透明覆盖并在没有网络时激活它,这样用户只能看到内容,但无法执行任何操作.还添加`<app-no-network>`一个名为`show`的属性,它将显示页面的一些小改动,如**YouTube**在其Android应用程序上. (2认同)

Rav*_*vta 6

经过一些搜索,并在@AlokeT 的回答的帮助下。我得到了解决这个问题的方法。

@AlokeT 的建议是在用户失去他/她的网络后立即显示连接丢失页面。但我的要求是在他/她尝试导航到另一个页面时显示该连接丢失页面。

在这个答案中,我刚刚补充说,那个缺失的部分。

为此,我只是isNetworkStopped从 Guard更新该标志,因为每个 CanActivate 守卫都在导航开始之前执行。因此,当用户更改路径时,将显示连接丢失组件。

NetworkService我在 NetworkGuard 中使用了一个代码,

@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;
    });
  }
}
Run Code Online (Sandbox Code Playgroud)

在上面的代码中,我刚刚添加了一个标志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;
  }
}
Run Code Online (Sandbox Code Playgroud)

基于那个标志,我设法显示了 ConnectionLost 组件。对于ConnectionLost基于根组件模板的条件添加该组件。

应用程序组件.html

<router-outlet *ngIf="!networkService.isNetworkStopped"></router-outlet>
<app-connection *ngIf="networkService.isNetworkStopped"></app-connection>
Run Code Online (Sandbox Code Playgroud)

从 ConnectionLost 组件中,如果用户单击重新加载按钮。通过检查网络连接,我更新isNetworkStoppedNetworkService.