具有可观察订阅值的 Angular CanDeactivate Router Guard [英] Angular CanDeactivate Router Guard with an Observable Subscribed Value

查看:31
本文介绍了具有可观察订阅值的 Angular CanDeactivate Router Guard的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我一直在尝试编写一个 canDeactivate 守卫来检查可观察流中的保存状态并相应地工作.

我的服务是这样的

import { Injectable } from '@angular/core';从 'rxjs/ReplaySubject' 导入 { ReplaySubject };从 'rxjs/Observable' 导入 { Observable };@Injectable()导出类 EditModelService {private SavingModelDataSource = new ReplaySubject();SavingModelData$ = this. SavingModelDataSource.asObservable();公共 setSavingModelData(状态:布尔值){this. SavingModelDataSource.next(state);}}

我的守卫像

import { Injectable } from '@angular/core';从@angular/router"导入 { CanDeactivate, ActivatedRouteSnapshot, RouterStateSnapshot };从 'rxjs/Observable' 导入 { Observable };从 './edit-model.service' 导入 { EditModelService };@Injectable()导出类 EditModelCanDeactivateGuardGuard {私人保存状态:布尔值;构造函数(私有 editModelService:EditModelService) { }可以停用(currentRoute: ActivatedRouteSnapshot,当前状态:RouterStateSnapshot): Observable|Promise<布尔值>|布尔{this.editModelService.savingModelData$.subscribe(保存 => {this. SavingState = 储蓄;});如果(this. SavingState){返回 this.editModelService.savingModelData$.first();} 别的 {返回 this.editModelService.savingModelData$.first();}}}

基本上,它从服务中获取 saveState 的值并根据状态返回,因此路由器的 canDeactivate 属性接收一个布尔值.由于守卫中的 this.savingState 值总是被订阅,所以我认为下面的条件没有问题.

通过一些搜索,我发现了这个

我在导入路由器配置的模块内提供了路由器防护.这也是提供服务的地方.

我在这里做错了什么?我刚开始使用路由器防护(尤其是使用可观察的 canDeactivate),感谢您的任何帮助.

解决方案

您的 Guard Service 必须实现功能才能完全实现 CanActivateCanDeactivate 界面.尝试更改为

来自

@Injectable()导出类 EditModelCanDeactivateGuardGuard {

@Injectable()导出类 EditModelCanDeactivateGuardGuard 实现 CanActivate、CanDeactivate{

你的 CanDeactivate 也应该改为 canDeactivate

 canDeactivate() {}

试用解决方案后更新:

另外,改变

来自

canDeactivate(currentRoute: ActivatedRouteSnapshot,当前状态:RouterStateSnapshot): Observable|Promise<布尔值>|布尔...

canDeactivate(): Observable|Promise<布尔值>|布尔...

I've been trying to write a canDeactivate guard to check a saving state from an observable stream and work accordingly.

My service goes as this

import { Injectable } from '@angular/core';
import { ReplaySubject } from 'rxjs/ReplaySubject';

import { Observable } from 'rxjs/Observable';

@Injectable()
export class EditModelService {

  private savingModelDataSource = new ReplaySubject<boolean>();

  savingModelData$ = this.savingModelDataSource.asObservable();

  public setSavingModelData(state: boolean) {
    this.savingModelDataSource.next(state);
  }

}

My guard goes as

import { Injectable } from '@angular/core';
import { CanDeactivate, ActivatedRouteSnapshot, RouterStateSnapshot } from '@angular/router';

import { Observable } from 'rxjs/Observable';

import { EditModelService } from './edit-model.service';

@Injectable()
export class EditModelCanDeactivateGuardGuard {
  private savingState: boolean;

  constructor(
    private editModelService: EditModelService
  ) { }

  CanDeactivate(
    currentRoute: ActivatedRouteSnapshot,
    currentState: RouterStateSnapshot
  ): Observable<boolean> | Promise<boolean> | boolean {

    this.editModelService.savingModelData$.subscribe(saving => {
      this.savingState = saving;
    });


    if (this.savingState) {
      return this.editModelService.savingModelData$.first();
    } else {
      return this.editModelService.savingModelData$.first();
    }

  }
}

Basically, it takes the value of the savingState from the service and returns according to the state so the router's canDeactivate attribute receives a boolean. Since the value this.savingState in the guard is always subscribed I don't think there is an issue with the conditional goes below.

With some search I came across this answer and tried doing the guard code as

return this.editModelService.savingModelData$.first();

Of course, I've imported first() here as import 'rxjs/add/operator/first';.

It returns an observable from the guard just to see whether that is working fine or if that is something to do with the way I am returning. But, in both of the scenarios, I get the error as shown in the image below.

I've provided the router guard inside the module where the router configuration is imported. That's where the service is provided as well.

What am I doing here wrong? I am new to using router guards(especially, canDeactivate with an observable) and any help is appreciated.

解决方案

Your Guard Service must implement function to fully implement that CanActivate or CanDeactivate interface. Try changing as

From

@Injectable()
export class EditModelCanDeactivateGuardGuard {

To

@Injectable()
export class EditModelCanDeactivateGuardGuard  implements CanActivate, CanDeactivate<boolean>{

also your CanDeactivate should be changed to canDeactivate

 canDeactivate() {

 }

Updated after trying out the solution:

Also, change

From

canDeactivate(
    currentRoute: ActivatedRouteSnapshot,
    currentState: RouterStateSnapshot
): Observable<boolean> | Promise<boolean> | boolean ...

To

canDeactivate(): Observable<boolean> | Promise<boolean> | boolean...

这篇关于具有可观察订阅值的 Angular CanDeactivate Router Guard的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆