如何在 Angular2 的 observable 中创建一个 observable [英] How to create an observable within an observable in Angular2

查看:32
本文介绍了如何在 Angular2 的 observable 中创建一个 observable的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我可能不在这个过程中,但这里是:

I might be off on the process, but here goes:

我有一个 angular2 服务.此服务的数据源将是 localstorage... 稍后在使用 http 的数据库调用返回时可选地更新.因为我想在各种来源回来时更新返回的数据,所以我似乎想使用一个 observables.现在,我只是想把这个概念弄下来,所以我跳过了本地存储方面......这有多种方法.

I have an angular2 service. The source for the data of this service is going to be localstorage... later optionally updated when a DB call using http returns. Because I'll be wanting to update the data returned as the various sources come back, it appears I want to use an observables. For now, I'm just trying to get the concept down, so I've skipped the localstorage aspect... but I'm including the 'backstory' so it makes (some) sense as to why I'm wanting to do this in multiple methods.

我的想法是我会有一个getHTTPEvents()"方法,它会返回一个observable,有效载荷是来自数据库的事件.(理论是在未来的某个时候我也会有一个getLSEvents()"方法,可以在那里捎带回去)

My thought was I would have a "getHTTPEvents()" method that would return an observable with the payload being the events from the DB. (the theory being that at some point in the future I'd also have a 'getLSEvents()' method that would piggy back in there)

为了模拟它,我有这个代码:

To mock that up, I have this code:

private eventsUrl = 'app/mock-events.json';
getHTTPEvents() : Observable<Array<any>> { 
    return this._http.get(this.eventsUrl)
        .map(response => response.json()['events'])
        .catch(this.handleError); // handle error is a logging method
}

我的目标是创建一种方法,允许对返回的事件进行过滤,但仍向服务用户返回可观察对象.这就是我的问题所在.为了这个目标,我有一个公共方法,该方法将由服务的用户调用.(尝试使用此处的模式 https://coryrylan.com/blog/angular-2-observable-data-services)

My goal would be to create a method that allows filtering on the returned events yet still returns an observable to users of the service. That is where my problem is. With that goal, I have a public method which will be called by users of the service. (attempted to use pattern from here https://coryrylan.com/blog/angular-2-observable-data-services)

public getEvents(key:string,value:string) : Observable<Array<any>> {
    var allEventsObserve : Observable<Array<any>> = this.getHTTPEvents();
    var filteredEventsObserve : Observable<Array<any>>;


    allEventsObserve 
    .subscribe(
        events => {
            for(var i=0;i<events.length;i++) {
                if(events[i][key]==value) {
                    console.log('MATCH!!!' + events[i][key]); // THIS WORKS!
                    return new Observable(observer => filteredEventsObserve = observer);  // what do I need to return here?  I want to return an observable so the service consumer can get updates
                }
            }
            return allEventsObserve
        },
        error =>  console.error("Error retrieving all events for filtering: " + error));

}

以上方法无效.我看过很多视频并阅读了很多关于 observable 的教程,但除了创建和使用 http observable 之外,我找不到什么比这更深入的了.

The above doesn't work. I've watch lots of videos and read lots of tutorials about observables, but nothing I can find seems to go more indepth other than creating and using the http observable.

我进一步尝试了这种制作新 observable 的方法:

I further tried this method of making the new observable:

var newObs = Observable.create(function (observer) {
                    observer.next(events[i]);
                    observer.complete(events[i]);
                });

虽然至少可以编译,但我不确定如何在正确的时间返回"它......因为我无法在 allEventsObserve.subscribe 方法之外创建"它(因为事件"不会"t 存在)并且不能(似乎)从订阅中返回"它.我也不完全确定我将如何触发"下一个"......?

And while at least that compiles, I'm not sure how to 'return' it at the right time... as I can't "Create" it outside the allEventsObserve.subscribe method (because 'events' doesn't exist) and can't (seem) to "return" it from within the subscribe. I'm also not entirely sure how I'd then "trigger" the 'next'...?

我是否需要修改 allEventsObserve 中的数据并以某种方式简单地返回它?我是否使用正确的有效载荷创建了一个新的可观察对象(如上所述) - 如果是,我该如何触发它?等等...我在这里检查过:如何在 angular2 上声明一个可观察的 但似乎无法跟踪第二个"可观察对象是如何触发的.也许我整个范式都错了?

Do I need to modify the data within allEventsObserve and somehow simply still return that? Do I make a new observable (as attempted above) with the right payload - and if so, how do I trigger it? etc... I've checked here: How to declare an observable on angular2 but can't seem to follow how the 'second' observable gets triggered. Perhaps I have the entire paradigm wrong?

推荐答案

您似乎误解了 RxJS 运算符(例如 mapfilter 等)的含义实际返回,我认为纠正这将使解决方案清晰.

It appears that you're misunderstanding what an RxJS operator (like map, filter, etc) actually returns, and I think correcting that will make the solution clear.

考虑这个简短的例子:

allEventsObserve
  .map(events => {
    return 'this was an event';
  })

诚然,这是一个非常无用的例子,因为来自 events 的所有数据都丢失了,但现在让我们忽略它.上面代码的结果不是字符串数组或其他任何东西,它实际上是另一个Observable.这个 Observable 只会为 allEventsObserve 发出的每个事件数组发出字符串 'this was an event' 这就是什么允许我们在 observables 上链接操作符——每个操作符在链返回一个新的 Observable,它发出以某种方式修改过的项目,即前一个操作符.

Granted, it's a pretty useless example since all of the data from events is lost, but let's ignore that for now. The result of the code above is not an array of strings or anything else, it's actually another Observable. This Observable will just emit the string 'this was an event' for each array of events emitted by allEventsObserve This is what allows us to chain operators on observables -- each operator in the chain returns a new Observable that emits items that have been modified in some way be the previous operator.

allEventsObserve 
  .map(events => {
    return 'this was an event';
  }) 
  .filter(events => typeof events !== 'undefined') 

allEventsObserve 显然是一个 ObservableallEventsObserve.map() 计算结果为 Observable,所以allEventsObserve.map().filter().

allEventsObserve is obviously an Observable, allEventsObserve.map() evaluates to an Observable, and so does allEventsObserve.map().filter().

因此,由于您希望您的函数返回一个 Observable,您暂时还不想调用 subscribe,因为这样做会返回一些不是真正的 可观察.

So, since you're expecting your function to return an Observable, you don't want to call subscribe just yet, as doing so would return something that isn't really an Observable.

考虑到这一点,您的代码可以通过以下方式重写:

With that in mind, your code can be rewritten in the following way:

public getEvents(key:string,value:string) : Observable<Array<any>> {
    var allEventsObserve : Observable<Array<any>> = this.getHTTPEvents();

    return allEventsObserve 
      .map(events => {
          var match = events.filter(event => event[key] == value);
          if (match.length == 0) {
            throw 'no matching event found';
          } else {
            return match[0];
          }
      })
      .catch(e => {
        console.log(e);
        return e;
      });

}

由于 getEvents 返回一个 Observable,因此您可以在代码的其他地方执行类似 getEvents().subscribe(events => processEvents()) 的操作 与他们互动.此代码还假定 this.getHTTPEvents() 返回一个 Observable.

Since getEvents returns an Observable, somewhere else in your code you would do something like getEvents().subscribe(events => processEvents()) to interact with them. This code also assumes that this.getHTTPEvents() returns an Observable.

另外,请注意我将您的 for 循环更改为对 filter,对数组进行操作.events 在这种情况下是一个普通的 JavaScript Array,所以被调用的 filter 不是同一个 filtercode> 作为 RxJS 操作符 filter.

Also, notice that I changed your for loop to a call to filter, which operates on arrays. events in this case is a plain-old JavaScript Array, so the filter that is getting called is not the same filter as the RxJS operator filter.

这篇关于如何在 Angular2 的 observable 中创建一个 observable的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆