[英]Rxjs Observable : subscribe to different values with one API call
I have a CRUD API where the get on the entity returns both the list and the total number of items for the current filter configuration. 我有一个CRUD API,其中实体上的get返回列表和当前过滤器配置的项目总数。
For example : GET /posts
例如: GET /posts
{
"items": [
{
"id": 1,
"title": "post title 1"
}
...
],
"total": 9
}
How can I create an observable where the HTTP query is executed only one time but where I can subscribe to either the total value or the items list ? 如何创建一个只能执行一次HTTP查询但我可以订阅总值或项目列表的observable?
I am in an Angular2 context with typescript. 我在带有typescript的Angular2上下文中。
I first tried this and it worked : 我第一次尝试这个并且它有效:
this.http.get('/api/posts').map(response => response.json()).subscribe(data => {
var items = data.items
var total = data.total
});
But I don't like this as I cannot use my interface for the Post entity (or I must defined an interface like that {items: Post, total: number}
this is not really graceful). 但我不喜欢这个,因为我不能将我的界面用于Post实体(或者我必须定义一个类似于{items: Post, total: number}
的界面,这不是很优雅)。 What I would like to do is something like this : 我想做的是这样的事情:
this.myPostService.totalObservable.subscribe(total => this.total = total)
this.myPostService.itemsObservable.subscribe(items => this.items = items)
But without triggering 2 queries. 但是没有触发2个查询。
I looked into this blog post : https://coryrylan.com/blog/angular-2-observable-data-services but I don't like the fact that you first subscribe and then call the list() method to load the list. 我查看了这篇博文: https : //coryrylan.com/blog/angular-2-observable-data-services但我不喜欢你先订阅然后调用list()方法加载列表的事实。
If you only need it to run once you can cache the value directly: 如果您只需要运行一次就可以直接缓存值:
var source = this.http.get('/api/posts').map(response => response.json()).publishLast();
//unsubscribe from this when you are done
var subscription = source.connect();
Then you can expose the two sources as: 然后,您可以将两个来源公开为:
var totalObservable = source.pluck('total');
var itemsObservable = source.pluck('items');
If on the other hand you need to call these Observables multiple times, then I would recommend that you wrap the get
in a triggering Observable and cache: 另一方面,如果需要多次调用这些Observable,那么我建议你将get
包装在一个触发的Observable和cache中:
var source = sourceTrigger
.startWith(0) //Optionally initialize with a starting value
//This ensures that only the latest event is in flight.
.flatMapLatest(() => this.http.get('/api/posts'), (_, resp) => resp.json())
.cache(1);
//Again expose these items using `pluck`
var totalObservable = source.pluck('total');
var itemsObservable = source.pluck('items');
In the second case the sourceTrigger
would be an Observable
that might be connected to a button event, so that each button click triggers a new request. 在第二种情况下, sourceTrigger
将是一个可能连接到按钮事件的Observable
,因此每次单击按钮都会触发一个新请求。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.