在异步加载的observable上使用安全导航操作符时,我遇到了一个将null值(而不是Lectures数组)传递给管道的问题:
<div *ngFor="let lecture of ((lecturesObservable | async)?.lectures | lectureType: 'main')" class="list-group-item">
讲授type.pipe.ts
import { Pipe, PipeTransform } from '@angular/core';
import { Lecture } from './lecture';
@Pipe({name: 'lectureType'})
export class LectureTypePipe implements PipeTransform {
transform(allLectures: Lecture[], lectureType: string): Lecture[]{
return allLectures.filter(lecture => lecture.type==lectureType);
}
}
一旦通过异步加载,讲座就会在没有管道的情况下进行精细迭代。这只是我在ng2中必须忍受的东西吗?
答案 0 :(得分:2)
当异步管道的输入observable尚未具有值时,它会通过设计解析为null。所以是的,你将不得不忍受它,通过设计管道来处理空输入。
答案 1 :(得分:1)
您还可以使用*ngIf
将块完全隐藏,然后将异步管道放置在此处。
请注意,let
的重要添加是分配给局部范围的变量。
在您的*ngFor
中使用该新变量lectures
,并确保该变量始终有一个值-这样您的管道就不会看到空值。
此外,您还会获得“免费”的“加载模板”
<div *ngIf="(lecturesObservable | async)?.lectures; let lectures; else loadingLectures">
<div *ngFor="let lecture of (lectures | lectureType: 'main')" class="list-group-item">
Lecture details...
</div>
</div>
<ng-template #loadingLectures>
Loading lectures!
</ng-template>
还请注意,*ngIf
可以在<ng-container>
上使用,而不会向DOM添加任何内容。
答案 2 :(得分:1)
您还可以制作直接与Observables一起使用的Angular管道。然后,您的过滤管道可以对 可观察值或“硬值”进行操作。
但是,当它使用可观察的对象时-您将永远不会收到错误,因为直到 个值,代码才会运行。
为此,在签名中(请注意any是一个数组)放在
transform(value: Observable<any> | any[])
,然后在内部检查可观察到的或“硬值”:
@Pipe({ name: 'filterLectures' })
export class FilterLecturesPipe implements PipeTransform {
constructor() {}
transform(value: Observable<any> | Array<any>, filterValue: any): Observable<any> | Array<any>
{
if (isObservable(value))
{
return value.pipe(filter(v => filterLecturesFunction(filterValue, v) ));
}
else
{
return (value as Array<any>).filter(v => filterLecturesFunction(filterValue, v) );
}
}
}
然后您可以像这样使用它-干净整洁:
但是,这可能是不好的做法,因为管道实际上对您的数据模型不应该了解太多。最好过滤客户端并公开各种可观察对象。
另一种方法是使通用的“ startWith”管道具有默认值:
@Pipe({ name: 'startWith' })
export class StartWithPipe implements PipeTransform {
constructor() {}
transform(value: Observable<any> | any, defaultValue: any): Observable<any> {
if (isObservable(value)) {
return value.pipe(startWith(defaultValue));
} else {
throw Error('Needs to be an observable');
}
}
}
这仅适用于可观察对象,因此您必须将其放在异步之前:
我不确定有关使用可观察值OR值的管道的官方指南,但是如果我需要与 一起使用的东西,这就是我要做的可以观察到的或实际值。
答案 3 :(得分:0)
您还可以使用例如提供默认值的BehaviorSubject
,这样当收到的值尚未收到时,Angular不会抛出。