Angular中的通用解析器防护

时间:2018-05-14 08:21:27

标签: angular guard resolver

是否可以在Angular中创建通用的Resolver Guard? 我尝试了以下内容:

export class BaseResolver <E extends BaseEntity, S extends BaseService> implements Resolve<E> {
      constructor(private service: S, private router: Router) {}

resolve(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): 
        Observable<E> {

        let id = route.paramMap.get('id');

        return this.service.getItem(id).pipe(
          take(1),
          map(item => {
            if (item) {
              return item;
            } else { // id not found
              this.router.navigate([this.service.getUrl()]);
              return null;
            }
          })
        );
      }

尝试配置路由器时出现编译错误

(用户实现BaseEntity接口)

resolve: {
              user: BaseResolver<User, UserService>
            }

错误是L

Type 'Observable<BaseEntity>' is not assignable to type 'Observable<E>'.
  Type 'BaseEntity' is not assignable to type 'E'

1 个答案:

答案 0 :(得分:0)

resolve方法应返回Resolve界面中定义的相同类型的对象。

解析界面定义: -

interface Resolve<T> {
  resolve(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<T> | Promise<T> | T
}

解决方案1: -

如果您想要特定类型,请定义一个基本抽象类,使用不同的类扩展并从resolve方法返回该类。

@Injectable()
export class TodoResolver implements Resolve<BaseEntity> {
  constructor(private service: SomeService, private router: Router) { }

  resolve(route: ActivatedRouteSnapshot, state: RouterStateSnapshot,
  ): Observable<ChildBaseEntity> {

    let id = route.paramMap.get('id');    
    return this.service.somemethod('id');    
  }
}


export abstract class BaseEntity {};

export class ChildBaseEntity extends BaseEntity {};

解决方案2: -

简单的解决方案是将解决方法的类型更改为Observable<any>

我不确定解决方案2是否适合您,因为您期望某种类型的安全性。