Angular 在角度2+中依次执行分解器;
考虑到以下路线:Angular 在角度2+中依次执行分解器;,angular,angular2-routing,Angular,Angular2 Routing,考虑到以下路线: path: '', component: MyComponent, resolve: { foo: FooResolver, bar: BarResolver } 有没有办法告诉angular执行第一个分解器foosolver,只有在第一个分解器完成后才执行第二个分解器BarResolver。如果Foo和Bar应串联解析,则它们应为单个FooBar解析程序。如果它们应该自己在其他路径中使用,FooBar可以包装Foo和Bar解析器: class FooBarR
path: '',
component: MyComponent,
resolve: {
foo: FooResolver,
bar: BarResolver
}
有没有办法告诉angular执行第一个分解器
foosolver
,只有在第一个分解器完成后才执行第二个分解器BarResolver
。如果Foo
和Bar
应串联解析,则它们应为单个FooBar
解析程序。如果它们应该自己在其他路径中使用,FooBar
可以包装Foo
和Bar
解析器:
class FooBarResolver implements Resolve<{ foo: any, bar: any }> {
constructor(
protected fooResolver: FooResolver,
protected barResolver: BarResolver
) {}
async resolve(route): Promise<{ foo: any, bar: any }> {
const foo = await this.fooResolver.resolve(route);
const bar = await this.barResolver.resolve(route);
return { foo, bar };
}
}
class FooBarResolver implements Resolve<Observable<any>> {
constructor(
protected fooResolver: FooResolver,
protected barResolver: BarResolver
) { }
resolve(): Observable<any>
{
return this.fooResolver.resolve().pipe(
concat(this.barResolver.resolve()),
concat(this.barResolver.resolve())
);
}
}
class-FooBarResolver实现解析{
建造师(
受保护的fooResolver:fooResolver,
受保护的barResolver:barResolver
) {}
异步解析(路由):承诺{
const foo=等待这个.foosolver.resolve(路由);
const bar=等待此.barResolver.resolve(路由);
返回{foo,bar};
}
}
FooBar
应了解从Foo
和Bar
返回的承诺或可观察到的事实,以便正确解决这些问题。否则,应添加额外的安全装置,如等待可观察。从(this.foosolver.resolve(route)).toPromise()
FooBar
和Foo
或Bar
不应出现在同一路径中,因为这将导致重复的分辨率。我发现了一个稍微优雅的解决方案,如果您不关心所有解析程序的结果,可以使用该解决方案:
class FooBarResolver implements Resolve<{ foo: any, bar: any }> {
constructor(
protected fooResolver: FooResolver,
protected barResolver: BarResolver
) {}
async resolve(route): Promise<{ foo: any, bar: any }> {
const foo = await this.fooResolver.resolve(route);
const bar = await this.barResolver.resolve(route);
return { foo, bar };
}
}
class FooBarResolver implements Resolve<Observable<any>> {
constructor(
protected fooResolver: FooResolver,
protected barResolver: BarResolver
) { }
resolve(): Observable<any>
{
return this.fooResolver.resolve().pipe(
concat(this.barResolver.resolve()),
concat(this.barResolver.resolve())
);
}
}
class-FooBarResolver实现解析{
建造师(
受保护的fooResolver:fooResolver,
受保护的barResolver:barResolver
) { }
resolve():可观察
{
返回此.foosolver.resolve().pipe(
concat(this.barResolver.resolve()),
concat(this.barResolver.resolve())
);
}
}
我使用它来触发服务中的数据加载。因为他们将数据/isLoading/错误写入Akita存储,所以我不关心解析器的结果。我在单个
解析器中使用CombineTest
解决了这个问题。您可以这样做:
@Injectable({providedIn: 'root'})
export class FooBarResolver implements Resolve<any> {
constructor(
private readonly fooResolver: FooResolver,
private readonly barResolver: BarResolver
) {}
resolve() {
return combineLatest(
this.fooResolver.resolve(),
this.barResolver.resolve()
).pipe(map(([users, posts]) => ({users, posts})))
}
}
@Injectable({providedIn:'root'})
导出类FooBarResolver实现解析{
建造师(
私有只读fooResolver:fooResolver,
专用只读barResolver:barResolver
) {}
解决(){
返回组合测试(
此.foosolver.resolve(),
this.barResolver.resolve()
).pipe(映射([users,posts])=>({users,posts})))
}
}
另一个选项是包装依赖路由,并在包装器上使用必要的解析器
即
*如果遇到相对路径解决问题,请尝试使用
relativeLinkResolution: "corrected"
在forRoot路由器方法中。更多信息请参见此处无论您想做什么。有一种更好的方法。这取决于foo
和bar
是什么,以及为什么要按此顺序解决它们。但一般来说,这是可以通过FooBarResolver实现的,它可以解析为包含foo和bar的对象。@estus我正在考虑这样做,如果没有其他方法,我会,但是我更喜欢使用不同的解析器来实现重用。@estus基本上是从数据库检索的json对象,我不关心执行顺序,但它们必须一个接一个地执行。我有同样的问题,但更复杂。在我的案例中,bar
和baz
依赖于foo
,但baz
在某些路线中是可选的。最终我得到了处理可选Baz的FooBarBaz
解析器。据我所知,目前没有更好的方法。@DanyAuthier与任何其他解析器一样,它在路由上被指定为resolve:{fooBar:FooBarResolver}
,在路由组件中,解析的数据可用作activatedRoute.data['fooBar'].foo
等。