在Angular 2+中一个接一个地执行解析器

问题描述 投票:9回答:3

鉴于以下路线:

path: '',
component: MyComponent,
resolve: {
    foo: FooResolver,
    bar: BarResolver
}

有没有办法告诉角度来执行第一个解析器FooResolver,并且只有在第一个解析器完成后才执行第二个解析器BarResolver

angular angular2-routing
3个回答
20
投票

解析器并行解析。如果FooBar应该被串联解决,那么它们应该是一个单独的FooBar解析器。如果他们应该在其他路线中自己使用,FooBar可以包装FooBar解析器:

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 };
  }
}

FooBar应该知道这一事实,如果它是从FooBar返回的承诺或可观察的,以便妥善解决它们。否则应添加额外的安全装置,如await Observable.from(this.fooResolver.resolve(route)).toPromise()

FooBarFooBar不应出现在同一路线内,因为这将导致重复的决议。


1
投票

我发现了一个稍微优雅的解决方案,如果您不关心所有解析器的结果,可以使用它:

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())
        );
    }
}

我使用它来触发我的服务中的数据加载。因为他们将数据/ isLoading /错误写入秋田存储,我不关心解析器的结果。


0
投票

我在单个combineLatest中使用resolver解决了这个问题。你可以这样做:

@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})))
  }
}
© www.soinside.com 2019 - 2024. All rights reserved.