1

一段时间以来一直在尝试在我的应用程序中实现基因解析器。基于我的直觉,我的第一个实现给了我确切的结果,因为这个 SO 问题:如何提供在 Angular4 中使用泛型的服务?,这当然也给了我确切的错误。

我尝试使用例外答案(使用InjectionToken)解决它,但无法让它工作,也许我在使用InjectionToken我当前的代码方面不够熟练:

GenericResolverService

`export interface GetItem<T> {
  getItem(id: number): Observable<T>;
 }

@Injectable()
export class GenericResolverService<T, U extends GetItem<T>> 
  implements Resolve<T> {

constructor(private dataService: U,
            private router: Router) {

}

resolve(route: ActivatedRouteSnapshot, 
      stata: RouterStateSnapshot):
  Observable<T> | Observable<never> {
  const itemId = +route.paramMap.get('id');

  return this.dataService.getItem(itemId).pipe(
    take(1),
    mergeMap(item => {
        if (item) {
            return of(item);
        } else {
            this.router.navigate(['/error/not-found']);
            return EMPTY;
        }
    })
  );
}
}`

路由器模块

const ITEM_RESOLVER = 
    new InjectionToken<GenericResolverService<ItemMasterData,   ItemMasterDataService>>
    ('itemResolver');

const routes: Routes = [
{ 
    path: ':id', component: ItemMasterDataEditComponent,
    resolve: {
        item: ITEM_RESOLVER
    } 
}
];

 @NgModule({
imports: [RouterModule.forChild(routes)],
exports: [RouterModule],
providers: [{ provide: ITEM_RESOLVER, useClass: GenericResolverService}]
})
export class ItemMasterDataRoutingModule { }   

ItemMasterDataService

@Injectable()
export class ItemMasterDataService implements GetItem<ItemMasterData> {

  public getItem(id: number): Observable<ItemMasterData> {

  ...
}

当前代码抛出错误:

错误:无法解析 GenericResolverService 的所有参数:(?, [object Object])。

我究竟做错了什么?

4

1 回答 1

1

Angular 要求 DI 令牌在运行时可用,但您使用的泛型类型将从生成的 JavaScript 中消失。

如果您仔细阅读您链接的问题的答案,您会注意到根本没有提供基类泛型而是派生类:

providers: [{ provide: MESSAGE_RESOLVER, useClass: MessageResolver }]
                                                   ^^^^^^^^^^^^^^^^^

在其构造函数中包含特定标记:

export abstract class DetailResolver<T, R extends Repository<T>> implements Resolve<T> {
   constructor(protected repositoryService: R, protected router: Router) {}
}

@Injectable()
export class MessageResolver extends DetailResolver<Message, MessageService> {
   constructor(repositoryService: MessageService, router: Router) {
                                  ^^^^^^^^^^^^^^
                                  available at runtim
     super(repositoryService, router);
   }
}

在您的示例中,您仍在尝试为类提供通用构造函数参数,但 Angular 不知道要实例化哪个类。

因此,您可以像上面的示例一样创建派生类,也可以利用 DI(useFactory) 的替代配方:

{
  provide: ITEM_RESOLVER,
  useFactory: (service, router) => new GenericResolverService(service, router),
  deps: [ItemMasterDataService, Router]
}

此外,您可以使用泛型类作为标记:

const routes: Routes = [
  { 
    path: ':id', component: ItemMasterDataEditComponent,
    resolve: {
        item: GenericResolverService
    } 
  }
];

@NgModule({
  imports: [RouterModule.forChild(routes)],
  exports: [RouterModule],
  providers: [
     ItemMasterDataService,
     {
       provide: GenericResolverService,
       useFactory: (service, router) => new GenericResolverService(service, router),
       deps: [ItemMasterDataService, Router]
     }
  ]
})
export class ItemMasterDataRoutingModule { }  

另一种选择是为您的dataService

constructor(protected dataService: SomeBaseDateServiceClass) {}

并在应用程序的不同级别上提供不同的实现:

{ provide: SomeBaseDateServiceClass, useClass: ItemMasterDataService }
于 2019-10-25T07:12:03.080 回答