问题描述
我正在尝试延迟加载组件,并且遵循了《 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()是贪婪的,它可以确保它仅返回一个元素或抛出错误