我可能会关注这个过程,但是这里有:
我有一个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但似乎无法跟踪“第二个”观察者是如何被触发的。也许我的整个范式都错了?
答案 0 :(得分:1)
您似乎误解了RxJS运算符(如map
,filter
等)实际返回的内容,并且我认为纠正这将使解决方案变得清晰。
考虑这个简短的例子:
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
显然是Observable
,allEventsObserve.map()
评估为Observable
,allEventsObserve.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
。