Angular 8: как синхронизировать Angular Разрешить - PullRequest
0 голосов
/ 30 апреля 2020

Доброе утро, мой вопрос немного сложен;

мы находимся внутри app.module.ts , в частности, в RouterModule область:

RouterModule.forRoot([
  {path: 'xxx/:xxx', component: XxxComponent},
  {path: '', redirectTo: 'homepage', pathMatch: 'full'},
  {path: 'homepage', component: HomepageComponent, resolve: {
      answerCallHttp1: CallHttp1Resolve,
      answerCallHttp2: CallHttp2Resolve,
      answerCallHttp3: CallHttp3Resolve
    }},
  {path: 'error', component: ErrorComponent}
])

Теперь моя проблема заключается в следующем:

, учитывая, что answerCallHttp1, answerCallHttp2 и answerCallHttp3 имеют разное время отклика, например, answerCallHttp1 имеет гораздо более быстрое время отклика чем answerCallHttp2, который имеет намного более медленное время отклика;

как заставить все answerCallHttp * работать, а затем после выполнения всего answerCallHttp * можно ли загрузить компонент домашней страницы ??

как мне сказать код: "первый финал sh все решают после загрузки" HomepageComponent "??

ОБНОВЛЕНИЕ :

I пытался использовать этот метод, рекомендованный пользователем, но он генерирует бесконечное число l oop вызовов Http :

resolve(
    route: ActivatedRouteSnapshot,
    state: RouterStateSnapshot
  ): Observable<any> | Promise<any> | any {
    return forkJoin({
      auth: this.memory.isToken(),
      userInfo: this.porcoDio.get(this.api + '/getUserInformation', {headers: new HttpHeaders({'Auth': this.memory.getToken()})}).subscribe(),
      retailers: this.porcoDio.get(this.api + '/retailer', {headers: new HttpHeaders({'Auth': this.memory.getToken()}),params: new HttpParams().set('system_device', 'desktop').set('system_platform', this.getBrowserName())}).subscribe()
    });
  }

это все Разрешить :

callHttp1Resolve.ts

 resolve(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<any> | Promise<any> | any {return this.memory.isToken();}

callHttp2Resolv e.ts

 resolve(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<any> | Promise<any> | any {this.porcoDio.get(this.api + '/getUserInformation', {headers: new HttpHeaders({'Auth': this.memory.getToken()})}).subscribe(userInfo => {return userInfo;});}

callHttp3Resolve.ts

 resolve(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<any> | Promise<any> | any {this.porcoDio.get(this.api + '/retailer', {headers: new HttpHeaders({'Auth': this.memory.getToken()}), params: new HttpParams().set('system_device', 'desktop').set('system_platform', this.getBrowserName())}).subscribe(retailer => {return retailer;});}

Ответы [ 2 ]

1 голос
/ 30 апреля 2020

Вы получаете это «из коробки»: представление создается только после того, как все преобразователи сделаны.

Вы можете проверить это, поместив несколько операторов console.log в ngOnInit вашего компонента и в сами решатели (например: return this.httpClient.get(/* ... */).pipe(tap(() => console.log('Request completed'))).

1 голос
/ 30 апреля 2020

Вы можете иметь только один распознаватель и выполнять все HTTP-вызовы с него:

export class CombinedResolverService implements Resolve<{[key: string]: any}> {
  resolve(route: ActivatedRouteSnapshot, state: RouterStateSnapshot)
    : Observable<{[key: string]: any}> {
    return forkJoin({
        answerCallHttp1: this.http.get(...), // URL 1
        answerCallHttp2: this.http.get(...), // URL 2
        answerCallHttp3: this.http.get(...), // URL 3
      });
  }
}

Приведенный выше подход работает только с версиями rx js> = 6.5. Если вы используете предыдущую версию, вы должны сделать:

export class CombinedResolverService implements Resolve<{[key: string]: any}> {
  resolve(route: ActivatedRouteSnapshot, state: RouterStateSnapshot)
    : Observable<{[key: string]: any}> {
    return forkJoin(
        this.http.get(...), // URL 1
        this.http.get(...), // URL 2
        this.http.get(...), // URL 3
      ).pipe(
        map(([answerCallHttp1, answerCallHttp2, answerCallHttp3]) => ({
            answerCallHttp1, answerCallHttp2, answerCallHttp3
          }))
      );
  }
}

[ОБНОВЛЕНИЕ]: Для комментариев я бы предложил следующие изменения:

call1HttpResolve .ts

Поскольку isToken() является , а не наблюдаемой, мы превратим ее в наблюдаемую с помощью оператора of (forkJoin выше требует, чтобы его возвращение было наблюдаемый):

resolve(route: ActivatedRouteSnapshot, state: RouterStateSnapshot)
  : Observable<any> | Promise<any> | any {
  return of(this.memory.isToken());
}

call2HttpResolve.ts

Вы должны вернуть наблюдаемое здесь:

resolve(route: ActivatedRouteSnapshot, state: RouterStateSnapshot)
  : Observable<any> | Promise<any> | any {
  return this.porcoDio.get(this.api + '/getUserInformation', 
    {headers: new HttpHeaders({'Auth': this.memory.getToken()})});
}

call3HttpResolve.ts

Вы должны вернуть наблюдаемое здесь:

resolve(route: ActivatedRouteSnapshot, state: RouterStateSnapshot)
  : Observable<any> | Promise<any> | any {
  return this.porcoDio.get(this.api + '/retailer', {
    headers: new HttpHeaders({'Auth': this.memory.getToken()}), 
    params: new HttpParams()
        .set('system_device', 'desktop')
        .set('system_platform', this.getBrowserName())
    });
}

Наконец, в вашем компоненте:

ngOnInit() {
  this.route.data
    .subscribe(({answerCallHttp1, answerCallHttp2, answerCallHttp3}) => {
      // do whatever you want with the data
    });
}

[Заключительный комментарий]: Кстати, у @mbojko есть хорошее наблюдение в другом ответе. Я проверил, что он предлагает, и это работает (и я узнал новую функцию, это здорово!), Поэтому вам нужно будет сделать только предлагаемые изменения в call2HttpResolve.ts и call3HttpResolve.ts. Это путь наименьших усилий и одинаково эффективный.

Вы можете увидеть, как он работает в этой демонстрационной версии Stackblitz .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...