解析器未返回Firestore的数据以在Angular中加载组件

问题描述

我正在尝试延迟加载组件,并且遵循了《 Angular Guide》(Angular Guide: Preloading component data),但是我什至没有从解析器取回数据,因此该组件没有如图所示。让我们看一下我的简单代码

服务

export class OrdeRSService {
  constructor(private firestore: AngularFirestore,private http: HttpClient) {}

  getCoffeeOrders() {
    // return request = this.http.get('http://date.jsontest.com/'); // Works,but it's not the right data
    return this.firestore.collection<CoffeeOrder>('coffeeOrders').valueChanges();;
  }
}

解析器

import { Injectable } from '@angular/core';
import {
  Resolve,ActivatedRouteSnapshot,RouterStateSnapshot,} from '@angular/router';
import { Observable } from 'rxjs';
import { CoffeeOrder,OrdeRSService } from './shared/orders.service';

@Injectable({
  providedIn: 'root',})
export class GetCoffeeOrdersResolverService implements Resolve<CoffeeOrder[]> {
  constructor(private ordeRSService: OrdeRSService) {}

  resolve(
    route: ActivatedRouteSnapshot,state: RouterStateSnapshot
  ): Observable<CoffeeOrder[]> | any {
    console.log('GetCoffeeOrdersResolver');

    return this.ordeRSService.getCoffeeOrders();
  }
}

组件

import { Component,OnInit } from '@angular/core';
import { ActivatedRoute } from '@angular/router';
@Component({
  selector: 'app-order-list',templateUrl: './order-list.component.html',styleUrls: ['./order-list.component.css'],})
export class OrderListComponent implements OnInit {
  coffeeOrders;
  res;
  constructor(private route: ActivatedRoute) {}

  ngOnInit() {
    console.log('ngOnInit');
    this.route.data.subscribe(res => {
      console.log(res);
      this.res = res;
    })
  }
}

路由

import { NgModule } from '@angular/core';
import { Routes,RouterModule } from '@angular/router';
import { GetCoffeeOrdersResolverService } from './get-coffee-orders-resolver.service';
import { OrderListComponent } from './order-list/order-list.component';

const routes: Routes = [
  {
    path: '',component: OrderListComponent,resolve: { orders: GetCoffeeOrdersResolverService },},];

@NgModule({
  imports: [RouterModule.forRoot(routes)],exports: [RouterModule],})
export class AppRoutingModule {}

我的结构版本

Angular CLI: 10.1.7
Angular: 10.1.6
Agular Fire: 6.0.3
rxjs: 6.6.3
typescript: 4.0.3

This is my Gist with the files

解决方法

在感觉到请求不是由解析器终结之后,我尝试了一些方法,因此解决此问题的关键只是通过解析器中的变通管道完成请求。

export class GetPatientsResolverService implements Resolve<Patient[]> {
  constructor(private patientService: PatientService) {}

  resolve(
    route: ActivatedRouteSnapshot,state: RouterStateSnapshot
  ): Observable<Patient[]> {
    return this.patientService
      .getPatients()
      .valueChanges({ idField: 'id' })
      .pipe(take(1)); // HERE IS THE TRICK!
  }
}

管道调用中的 take(1)方法终止请求,然后可以等待答案将其正确地传递到解析器并进行服务。

为什么要使用take()而不是first()?

基本上:

  • take(n)不是贪婪的,因此将尝试使其返回集合中的前n个元素,并且如果集合为空则不会引发错误。
  • first()是贪婪的,它可以确保它仅返回一个元素或抛出错误