如何在Angular2

时间:2016-06-06 22:36:49

标签: javascript typescript angular rxjs

我可能会关注这个过程,但是这里有:

我有一个angular2服务。此服务的数据源将是localstorage ...稍后可选择在使用http返回DB调用时更新。因为我想要更新返回的数据,因为各种来源都会回来,看来我想要使用一个observables。就目前而言,我只是试图让这个概念失效,所以我已经跳过了本地存储方面......但我包括了“背景故事”,所以它让(某些)感觉到我为什么要做这有多种方法。

我的想法是我会有一个“getHTTPEvents()”方法,它会返回一个observable,其中有效负载是来自DB的事件。 (理论是,在未来的某个时候,我也会有一个'getLSEvents()'方法,可以在那里捎带)

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

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
}

我的目标是创建一个方法,允许对返回的事件进行过滤,但仍然向服务的用户返回一个observable。这就是我的问题所在。有了这个目标,我有一个公共方法,将由服务的用户调用。 (试图从这里使用模式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));

}

以上不起作用。我观看了很多视频并阅读了很多关于可观察量的教程,但除了创建和使用http observable之外,我找不到任何东西似乎更加深入。

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

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

至少那个编译,我不知道如何在正确的时间'返回'它...因为我不能在allEventsObserve.subscribe方法之外“创建”它(因为'事件'没有'存在)并且不能(似乎)从订阅中“返回”它。我也不完全确定我如何“触发”'下一个'......?

我是否需要修改allEventsObserve中的数据并以某种方式仍然返回?我是否使用正确的有效负载创建了一个新的可观察对象(如上所述) - 如果是这样,我该如何触发它?等等......我在这里查了一下:How to declare an observable on angular2但似乎无法跟踪“第二个”观察者是如何被触发的。也许我的整个范式都错了?

1 个答案:

答案 0 :(得分:1)

您似乎误解了RxJS运算符(如mapfilter等)实际返回的内容,并且我认为纠正这将使解决方案变得清晰。

考虑这个简短的例子:

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

当然,这是一个非常无用的例子,因为events的所有数据都丢失了,但是现在让我们忽略它。上面代码的结果不是字符串数组或其他任何内容,它实际上是另一个Observable。这个Observable将为'this was an event'发出的每个事件数组发出字符串allEventsObserve。这是允许我们在可观察数据上链接运算符的原因 - 链中的每个运算符都返回一个新的Observable发出以某种方式被修改的项目作为前一个运算符。

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

allEventsObserve显然是ObservableallEventsObserve.map()评估为ObservableallEventsObserve.map().filter()也是如此。

所以,既然你期望你的函数返回Observable,你就不想再调用subscribe了,因为这样做会返回一些不是Observable的东西。

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

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

另外,请注意我已将for循环更改为对filter的调用,该调用对数组进行操作。在这种情况下,events是一个普通的JavaScript Array,因此被调用的filter与RxJS运算符filter不同filter