0

我正在尝试延迟加载一个组件,并且我已经遵循了这个 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

这是我的文件要点

4

1 回答 1

0

在发现请求不是由解析器结束后,我尝试了一些东西,因此解决此问题的关键点只是在我的解析器中使用解决方法管道完成请求。

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()是贪婪的,并确保它将只返回一个元素或抛出错误
于 2020-10-28T23:55:45.147 回答