【问题标题】:Make Angular resolver wait for images让 Angular 解析器等待图像
【发布时间】:2020-03-05 20:53:51
【问题描述】:

我可以做些什么来让解析器等待它从 API 获取图像。现在,Angular 等到收到数据,显示页面,然后尝试获取帖子的图像。

@Injectable()
export class DataResolverService implements Resolve<any> {
  constructor(
    private router: Router,
    private API: ApiService
  ) {}

  resolve(
    route: ActivatedRouteSnapshot,
    state: RouterStateSnapshot
  ): Observable<any> | Observable<never> {
    return this.API.getPostById(route.params.id).pipe(
      map(response => {
        if (response["images"]) {
          const images = [];
          response["images"].forEach(image => {
            this.API.getImageById(image.id).subscribe(
              (img: any) => {
                const imageObject = {
                  url: window.URL.createObjectURL(img),
                };
                images.push(imageObject);
              }
            );
          });
          response["images"] = images;
          return response;
        }

        return response;
      })
    );
  }
}

【问题讨论】:

  • 看起来你嵌入了 Observable 的;所以解析器在第一个解析后解析。我怀疑您想返回内部可观察对象而不是外部可观察对象。应该有一个 rxjs 操作员来处理这个问题。可能是 MergeMap?
  • 你是对的。 SwitchMap 帮我解决了这个问题。

标签: javascript angular typescript angular-resolver


【解决方案1】:

试试:

@Injectable()
export class DataResolverService implements Resolve<any> {
  constructor(
    private router: Router,
    private API: ApiService
  ) {}

  resolve(
    route: ActivatedRouteSnapshot,
    state: RouterStateSnapshot
  ): Observable<any> | Observable<never> {
    return this.API.getPostById(route.params.id).pipe(
      switchMap(response => { // change this into a switchMap
        if (response["images"]) {
          return combineLatest(
            // combine all of the request for the images
            ...response["images"].map(image => this.API.getImageById(image.id)),
          ).pipe(
            map(images => images.map(image => ({ url: window.URL.createObjectURL(image) })),
            map(images => ({ response: images })), // This map may be unnecessary
          );
        } else {
         return of([]);
        }
      })
    );
  }
}

这应该让你开始。您的方法的问题是您订阅了内部可观察对象,我不认为路由解析器正在等待它。

【讨论】:

  • 它就像一个魅力。谢谢您的帮助。最后一张地图帮助我将图像附加到响应中。
【解决方案2】:

您在异步方法“this.API.getImageById(image.id)”解析之前返回“响应”。在返回之前,您必须等待所有异步迭代结束。有一些选项可以做到这一点,这是选项:

return this.API.getPostById(route.params.id).pipe(
      map(async response => {
        if (response["images"]) {
          const images = [];
          response["images"].forEach(image => {
           await this.API.getImageById(image.id).then(
              (img: any) => {
                const imageObject = {
                  url: window.URL.createObjectURL(img),
                };
                images.push(imageObject);
              }
            );
          });
          response["images"] = images;
          return response;
        }

        return response;
      })
    );

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-03-17
    • 2015-01-28
    • 2012-09-05
    • 2011-04-14
    • 1970-01-01
    • 2019-06-20
    • 2021-02-26
    相关资源
    最近更新 更多