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

时间:2019-02-18 15:08:14

标签: javascript angular web guard

我想要的是,如果网络不可用,并且用户尝试导航到下一页ConnectionLost,组件就会在那里。

但是如果没有网络并且用户不执行任何操作,则意味着不导航到第二页。那么就不会有连接丢失的页面。用户应停留在当前页面上。

为此,我实现了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;
  }
}

除了一种情况外,它都可以正常工作。 也就是说,如果我从浏览器中单击前进或后退,其更新URL connection-lost地址栏

我该如何解决这个问题? 可以看到示例Here

产生问题的步骤:

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

我只是不想用'/ connection-lost'更新URL,因为我在skipLocationChange: true的{​​{1}}方法中添加了router.navigate选项,但是仍然没有工作。

2 个答案:

答案 0 :(得分:5)

我不知道这是否是适合您的解决方案,但是我在我的项目中所做的工作紧随其后。

  

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>

让我知道它是否按照您需要的方式工作。

答案 1 :(得分:1)

经过一点搜索,并借助@AlokeT的答案。我已经解决了这个问题。

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

在这个答案中,我刚刚添加了缺失的部分。

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

我在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组件。通过检查网络连接,我更新了isNetworkStopped NetworkService 标志。