【问题标题】:Return an empty Observable from an Angular2 Service从 Angular2 服务返回一个空的 Observable
【发布时间】:2017-07-27 11:34:35
【问题描述】:

我正在构建一个 Angular 2 应用程序,它使用服务来收集数据。 该服务确实包含以下逻辑:

/* ========== CORE COMPONENTS ========== */
import { Injectable } from '@angular/core';
import { Http, Response } from '@angular/http';
import { Observable } from 'rxjs/Observable';
import 'rxjs/Rx';
import 'rxjs/add/operator/map';
import 'rxjs/add/operator/catch';

/* ========== MODELS ========== */
import { IApplicationViewModel } from './models/application.model';

/* ========== CONSTANTS ========== */
import { LogzillaServerConfiguration } from '../../app.configuration';

@Injectable()
export class ApplicationService {
    private getAllEndpoint = LogzillaServerConfiguration.host + '/api/administration/application/getAll';

    // Initializes a new instance of the 'ApplicationService'.
    constructor(private http: Http) { }

    // Get all the 'logzilla' applications.
    getApplications(): Observable<IApplicationViewModel[]> {
        return this.http.get(this.getAllEndpoint)
            .map((response: Response) => <IApplicationViewModel[]>response.json().model)
            .catch(this.handleError);
    }

    // Handle an error that occured while retrieving the data.
    // This method will throw an error to the calling code.
    private handleError(error: Response) {
        return Observable.empty();
    }
}

此服务的作用是从端点检索数据,并将其映射到模型,当确实发生错误时,我将返回一个空的 Observable

我还有一个解析器,用于在更改活动路由之前从服务加载数据。 这个解析器确实包含以下逻辑:

/* ========== CORE COMPONENTS ========== */
import { Injectable } from '@angular/core';
import { Resolve, ActivatedRouteSnapshot } from '@angular/router';

/* ========== APPLICATION SERVICES ========== */
import { ApplicationService } from './application.service';

/* ========== MODELS ========== */
import { IApplicationViewModel } from './models/application.model';
import { IApplicationLogLevel } from './models/applicationLevel.model';

// Defines the 'resolver' which is used to resolve the applications.
@Injectable()
export class ApplicationResolver implements Resolve<IApplicationViewModel[]> {

    // Initializes a new instance of the 'ApplicationResolver'.
constructor(private applicationService: ApplicationService) { }

// Get all the registered applications.
resolve(route: ActivatedRouteSnapshot) {
    return this.applicationService.getApplications();
}
}

我的路由定义是:

{ path: 'applications', component: ApplicationComponent, pathMatch: 'full', resolve: {
            application: ApplicationResolver
        }},

但是,当我浏览到 /applications 时,我收到了一个错误 Uncaught (in promise): Error: no elements in sequence.

编辑:添加组件

@Component({
    selector: 'logzilla-applications',
    templateUrl: './src/app/pages/applications/application.template.html'
})
@Injectable()
export class ApplicationComponent implements OnInit {
    hasApplications: boolean;
    applications: IApplicationViewModel[];
    errorMessage: string;

    // Initializes a new instance of the 'ApplicationComponent'.
    constructor (private route: ActivatedRoute) { 
        console.log('I am here.');
    }

    // This method is executed when the component is loaded.
    ngOnInit() { 

    }

我的组件的构造函数不是事件调用。 如何解决。

亲切的问候,

【问题讨论】:

  • 我们能看到ApplicationComponent
  • 如果将Observable.empty() 替换为Observable.of([]) 会发生什么
  • 我已将组件添加为编辑,但它几乎是空的,所以我不明白你为什么需要它:)à
  • @ChristopherMoore 将其更改为 Observable.of([]) 确实有效。但是,你能解释一下我为什么会有这种行为吗?
  • @Complexity - 让我添加一个包含更多细节的答案

标签: angular


【解决方案1】:

Observable.empty() 替换为Observable.of([])of 优于 empty 是官方 Angular Tour of Heroes 教程用来返回一个空的 observable 的方法,也是我在所有应用程序中一直使用的方法。

它们之间的区别似乎是是什么都不返回,还是一个空数组。

来自官方 rxjs 文档:

Observable.empty()

创建一个不向 Observer 发出任何项目并立即发出完整通知的 Observable。

Observable.of()

创建一个 Observable,它发出一些您指定为参数的值,一个接一个地发出,然后发出一个完整的通知。

【讨论】:

  • 感谢您的澄清。如果我的组件现在检索失败,或者没有返回数据,有什么办法吗?因为我可能想在检索失败时显示一些错误消息。
  • 如果我再次执行此操作,错误开始弹出,表明解析器中出现异常。
  • of([]).ifEmpty() 在订阅时返回 false。我认为您的意思是 of(),其中 of().ifEmpty 返回 true。奇怪的是 .from([]) 被认为是空的,而 from() 是不允许的。
【解决方案2】:

解析器尝试订阅给定的 Observable,并将 Observable 序列的第一个结果传递给组件(实际上是 ActivatedRoute 对象)。

但是由于您的 Observable 在发出结果之前触发了已完成的事件,因此解析器不会得到结果。这就是你的错误的来源。

您必须返回 Observable.of(null)Observable.of([]) 或类似的东西。 然后您可以处理组件中的空输入。

This 页面包含有关Observable.empty()函数的更多信息。

【讨论】:

  • Observable.of(null) 是这里的答案,如果你定义了你的 observable 的类型参数(例如Observable&lt;User&gt;
【解决方案3】:

你可以使用这个返回空的 observable -

return new Observable<HttpEvent<any>>();

你也可以使用类型来摆脱类型脚本错误。

【讨论】:

    猜你喜欢
    • 2022-11-09
    • 2016-11-27
    • 2017-03-07
    • 2017-04-17
    • 2017-03-29
    • 2018-04-06
    • 2021-11-07
    • 1970-01-01
    • 2017-04-06
    相关资源
    最近更新 更多