我有一个 TypeScript/Angular 2 Observable,它在我第一次调用时就完美运行。但是,我有兴趣将多个订阅者附加到同一个可观察对象并以某种方式刷新可观察对象和附加的订阅者。这是我得到的:
query(): Rx.Observable<any> {
return this.server.get('http://localhost/rawData.json').toRx().concatMap(
result =>
result.json().posts
)
.map((post: any) => {
var refinedPost = new RefinedPost();
refinedPost.Message = post.Message.toLowerCase();
return refinedPost;
}).toArray();
}
图片显示有一个刷新按钮,当按下该按钮时,会重新执行此可观察对象,并且连接到它的任何订阅者都会获得一组更新的数据。
我怎样才能做到这一点?
最佳答案
我不太了解 Angular2 和 Typescript,但 typescript 是 javascript 的超集,我做了以下假设(如果我错了请告诉我)这应该使以下 javascript 代码工作:
server.get
返回一个 promise (或数组或 Rx.Observable)posts
是post
的数组
您需要根据该按钮上的点击事件创建一个可观察对象,将点击映射到您的 GET
请求,其余的应该或多或少与您编写的一样。我无法测试它,但它应该遵循这些原则:
// get the DOM id for the button
var button = document.getElementById('#xxx');
// create the observable of refined posts
var query$ =
Rx.Observable.fromEvent(button, 'click')
.flapMapLatest(function (ev) {
return this.server.get('http://localhost/rawData.json')
})
.map(function (result){return result.json().posts})
.map(function (posts) {
return posts.map(function(post){
var refinedPost = new RefinedPost();
refinedPost.Message = post.Message.toLowerCase();
return refinedPost;
})
})
.share()
// subscribe to the query$. Its output is an array of refinedPost
// All subscriptions will see the same data (hot source)
var subscriber = query$.subscribe(function(refinedPosts){console.log(refinedPosts)})
一些解释:
- 每次点击都会产生对
server.get
的调用,该调用返回可观察兼容类型(数组、 promise 或可观察)。返回的 observable 被展平以从该调用中提取result
- 因为用户可以点击很多次,每次点击都会产生它的数据流,而我们只对最近一次点击的结果感兴趣(我在这里也做了另一个假设),所以我们使用运算符 flatMapLatest,它将执行flatMap 仅在最近一次点击生成的可观察对象上
- 我们提取帖子
posts
的数组,并从中创建一个refinedPost
的数组。最后,每次点击都会产生一个refinedPost
数组,我想这就是你想要的 - 我们共享这个 observable,因为您提到您将有多个订阅者,并且您希望所有订阅者看到相同的数据。
让我知道我的假设是否正确以及这是否对您有用。
另外我推荐你看看https://gist.github.com/staltz/868e7e9bc2a7b8c1f754
除了很好地提醒概念外,它还解决了与您的问题非常相似的刷新服务器调用问题。
关于javascript - 如何重启或刷新 Observable?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32741875/