Angular 2

时间:2016-08-03 19:13:37

标签: angular

在异步加载的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中必须忍受的东西吗?

4 个答案:

答案 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不会抛出。