0

我有一个正在运行的NGRX 数据实体服务,我想在访问路由之前预加载数据,因此我制作了一个解析器。

import { Injectable } from "@angular/core";
import {
  ActivatedRouteSnapshot,
  Resolve,
  RouterStateSnapshot,
} from "@angular/router";
import { Observable, race } from "rxjs";
import { filter, first, tap, mapTo } from "rxjs/operators";
import { ExerciseEntityService } from "./exercise-entity.service";

@Injectable()
export class ExercisesResolver implements Resolve<boolean> {
  constructor(private exercisesService: ExerciseEntityService) {}

  resolve(
    route: ActivatedRouteSnapshot,
    state: RouterStateSnapshot
  ): Observable<boolean> {
    return this.exercisesService.loaded$.pipe(
      tap((loaded) => {
        if (!loaded) {
          this.exercisesService.getAll();
        }
      }),
      filter((loaded) => !!loaded),
      first()
    );
  }
}

如果服务响应成功,则路由得到解析,但如果出现错误,解析器将无法解析。例如,如果服务返回错误,我该如何管理?我以这种方式尝试过比赛,但它不起作用:

import { Injectable } from '@angular/core';
import {
  ActivatedRouteSnapshot,
  Resolve,
  RouterStateSnapshot
} from '@angular/router';
import { Observable, race } from 'rxjs';
import { filter, first, tap, mapTo } from 'rxjs/operators';
import { ExerciseEntityService } from './exercise-entity.service';

@Injectable()
export class ExercisesResolver implements Resolve<boolean> {
  constructor(private exercisesService: ExerciseEntityService) {}

  resolve(
    route: ActivatedRouteSnapshot,
    state: RouterStateSnapshot
  ): Observable<boolean> {
    return race(
      this.exercisesService.loaded$.pipe(
        tap((loaded) => {
          if (!loaded) {
            this.exercisesService.getAll();
          }
        }),
        filter((loaded) => !!loaded),
        first()
      ),
      this.exercisesService.errors$.pipe(mapTo(true))
    );
  }
}

4

1 回答 1

0

在使用 combineLatest、mergeMap、race 和其他运算符尝试不同类型的方法后,以这种方式解决:

import { Injectable } from '@angular/core';
import {
  ActivatedRouteSnapshot,
  Resolve,
  RouterStateSnapshot
} from '@angular/router';
import { Observable, Subscriber } from 'rxjs';
import { filter, first, tap } from 'rxjs/operators';
import { ExerciseEntityService } from './exercise-entity.service';

@Injectable()
export class ExercisesResolver implements Resolve<boolean> {
  constructor(private exercisesService: ExerciseEntityService) {}

  resolve(
    route: ActivatedRouteSnapshot,
    state: RouterStateSnapshot
  ): Observable<boolean> {
    const loadExercises = (subscriber: Subscriber<boolean>) => {
      this.exercisesService.loading$
        .pipe(
          filter((loading) => !loading),
          first()
        )
        .subscribe({
          next: (loading) => {
            subscriber.next(true);
            subscriber.complete();
          }
        });
      this.exercisesService.getAll();
    };

    const resolve$ = new Observable<boolean>((subscriber) => {
      this.exercisesService.loaded$
        .pipe(
          tap((entitiesLoaded) => {
            if (!entitiesLoaded) {
              loadExercises(subscriber);
            } else {
              subscriber.next(true);
              subscriber.complete();
            }
          })
        )
        .subscribe();
    });

    return resolve$;
  }
}

于 2021-11-11T06:24:37.690 回答