当没有结果返回时,如何防止Angular异步管道频繁进行服务器调用?

Dan*_*ick 7 typescript angular

async在ngFor中使用管道来观察Observable.Observable由访问我的服务器的服务创建,并且在枚举ngFor循环时的加载时间,服务正确地调用服务器.

现在对于我不理解的部分:当任何结果回来时,一切都按预期发生.但是,如果服务器响应说,404,并且没有可用于枚举的结果,则async管道会使服务继续触发请求,相隔毫秒.这显然不好.这里的设计期望是什么?如何优雅地处理在使用异步管道时返回错误的Observable?

在组件模板中:

<li *ngFor="let person of persons | async">{{person.id}}</li>
Run Code Online (Sandbox Code Playgroud)

在Component主体中:

get persons: Observable<Person[]> {
    return this.personService.list();
}
Run Code Online (Sandbox Code Playgroud)

在服务中:

list(): Observable<Person[]> {
    if (this.persons && this.persons.length) {
        return Observable.from([this.persons]);
    } else {
        return this.http.get('/person')
            .map((response: Response) => response.json())
            .map((data: Person[]) => {
                this.persons = data;
                return data;
            })
            .catch((error: any) => {
                let errMsg = "some error..."
                return Observable.throw(errMsg);
            });
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

Det*_*iel 7

我有一个非常类似的问题,这是由于Angular2变化检测的工作原理.有多种解决方案对我有用.

保存对observable的引用,以使其不会更改

现在,当你调用personsgetter时,它总是返回一个新的实例Observable(例如一个不同的对象),因此Angular重新评估整个事物,并且在下一个更改检测周期中,它再次执行,然后再次,......所以,这就是它如何解决:

@Component({
    selector: 'my-comp',
    template: `{{ _persons | async }}`,
}) export class MyComponent implements OnInit {
    ngOnInit() {
        this._persons = this.personService.list();
    }
}
Run Code Online (Sandbox Code Playgroud)

更改ChangeDetectionStrategyOnPush

你可能想告诉Angular:"我知道我在做什么,我会在发生一些变化时告诉你自己":

import { ChangeDetectionStrategy, ChangeDetectorRef, Component, OnInit } from '@angular/core';

@Component({
    changeDetection: ChangeDetectionStrategy.OnPush,
    selector: 'my-comp',
    template: `
      {{ persons | async }}
      <button (click)="reload">Reload</button>
    `,
}) export class MyComponent implements OnInit {
    constructor(private cd: ChangeDetectorRef) {}

    ngOnInit() {
        this.persons = this.personService.list();
    }

    reload() {
        this.persons = this.personService.list();
        // this tells Angular that a change occurred
        this.cd.markForCheck();
    }
}
Run Code Online (Sandbox Code Playgroud)

这两种解决方案都适用于我,我决定采用第二种方法,因为它也是一种优化