Angular 实施遗传解析器
Angular implementing a genetic resolver
一段时间以来,我一直在尝试在我的应用程序中实施遗传解析器。我的第一个基于直觉的实现给了我这个 SO 问题的确切结果:,这当然也给了我确切的错误。
我尝试使用例外答案(使用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> {
...
}
当前代码抛出错误:
Error: Can't resolve all parameters for GenericResolverService: (?,
[object Object]).
我做错了什么?
Angular 要求 DI 令牌在运行时可用,但您使用的通用类型将从生成的 JavaScript.
中消失
如果您仔细阅读所链接问题的答案,您会注意到基本泛型 class 根本没有提供,而是派生的 class:
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);
}
}
在您的示例中,您仍在尝试向 class 提供通用构造函数参数,但 Angular 不知道要实例化哪个 class。
因此您可以像上面的示例一样创建派生 class 或利用 DI(useFactory) 的替代配方:
{
provide: ITEM_RESOLVER,
useFactory: (service, router) => new GenericResolverService(service, router),
deps: [ItemMasterDataService, Router]
}
此外,您可以使用您的通用 class 作为标记:
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 }
一段时间以来,我一直在尝试在我的应用程序中实施遗传解析器。我的第一个基于直觉的实现给了我这个 SO 问题的确切结果:
我尝试使用例外答案(使用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> {
...
}
当前代码抛出错误:
Error: Can't resolve all parameters for GenericResolverService: (?, [object Object]).
我做错了什么?
Angular 要求 DI 令牌在运行时可用,但您使用的通用类型将从生成的 JavaScript.
中消失如果您仔细阅读所链接问题的答案,您会注意到基本泛型 class 根本没有提供,而是派生的 class:
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);
}
}
在您的示例中,您仍在尝试向 class 提供通用构造函数参数,但 Angular 不知道要实例化哪个 class。
因此您可以像上面的示例一样创建派生 class 或利用 DI(useFactory) 的替代配方:
{
provide: ITEM_RESOLVER,
useFactory: (service, router) => new GenericResolverService(service, router),
deps: [ItemMasterDataService, Router]
}
此外,您可以使用您的通用 class 作为标记:
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 }