我可能会偏离这个过程,但这里是:
我有一个 angular2 服务。该服务的数据源将是本地存储...稍后当使用 http 的数据库调用返回时可选择更新。因为当各种来源返回时我想要更新返回的数据,看来我想使用一个可观察对象。现在,我只是想把这个概念说清楚,所以我跳过了本地存储方面……但我包括了“背景故事”,所以它对我想做的事情有(一些)意义这有多种方法。
我的想法是我将有一个“getHTTPEvents()”方法,该方法将返回一个可观察对象,其有效负载是来自数据库的事件。 (理论是,在未来的某个时候,我还会有一个“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
}
我的目标是创建一种方法,该方法允许对返回的事件进行过滤,但仍向服务用户返回一个可观察对象。这就是我的问题所在。为了这个目标,我有一个公共(public)方法,该方法将被服务的用户调用。 (尝试使用此处的模式 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 可观察对象之外,我找不到更深入的内容。
我进一步尝试了这种制作新可观察对象的方法:
var newObs = Observable.create(function (observer) {
observer.next(events[i]);
observer.complete(events[i]);
});
虽然至少可以编译,但我不确定如何在正确的时间“返回”它...因为我无法在 allEventsObserve.subscribe 方法之外“创建”它(因为“事件”不t 存在)并且不能(似乎)从订阅中“返回”它。我也不完全确定我将如何“触发”“下一个”...?
我是否需要修改 allEventsObserve 中的数据并以某种方式简单地返回它?我是否使用正确的有效负载创建了一个新的可观察对象(如上所示)——如果是这样,我该如何触发它?等......我在这里检查过:How to declare an observable on angular2但似乎无法理解“第二个”可观察对象是如何被触发的。也许我的整个范式都错了?
最佳答案
看来您误解了 RxJS 运算符(如 map
、filter
等)实际返回的内容,我认为纠正这一点将使解决方案更加清晰。
考虑这个简短的例子:
allEventsObserve
.map(events => {
return 'this was an event';
})
当然,这是一个非常无用的示例,因为来自 events
的所有数据都丢失了,但我们暂时忽略它。上面代码的结果不是字符串数组或其他任何东西,它实际上是另一个 Observable
。这个 Observable 只会为 allEventsObserve
发出的每个事件数组发出字符串 'this was an event'
该链返回一个新的 Observable
,它发出以某种方式被修改为前一个运算符的项目。
allEventsObserve
.map(events => {
return 'this was an event';
})
.filter(events => typeof events !== 'undefined')
allEventsObserve
显然是一个 Observable
,allEventsObserve.map()
评估为一个 Observable
,所以也是allEventsObserve.map().filter()
。
因此,由于您期望您的函数返回一个 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
不是同一个 filter
作为 RxJS 运算符 filter
.
关于javascript - 如何在 Angular2 的可观察对象中创建可观察对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37667891/