typescript 如何在 Angular 2 中修改 Observable 中的数据?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/43508718/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to modify data in Observable in Angular 2?
提问by user961714
I am working on learning Angular 2 and Typescript. I am building a simple web application that grabs data from a WEB API and displays it in a list. Then once the user clicks an item in the list, they are taken to a details page.
我正在学习 Angular 2 和 Typescript。我正在构建一个简单的 Web 应用程序,它从 WEB API 获取数据并将其显示在列表中。然后一旦用户单击列表中的一个项目,他们就会被带到一个详细信息页面。
I have a service that I created to make the API call that does the following:
我创建了一个服务来进行 API 调用,它执行以下操作:
GetData() {
let data = this.http.get('http://server.name/api/GetData')
.map((res) => res.json());
return data;
}
Then in a component, I subscribe to the data like this:
然后在一个组件中,我订阅了这样的数据:
this.myService.GetData()
.subscribe((myService) => this.items = myService);
When the http.get returns, I would like to do some processing on the JSON objects before I return from the GetData() method. For example, add a new property called ID. Essentially something like the pseudo code below:
当 http.get 返回时,我想在从 GetData() 方法返回之前对 JSON 对象进行一些处理。例如,添加一个名为 ID 的新属性。本质上类似于下面的伪代码:
for each(item in data) {
item.ID = newID(); //method for creating IDs
}
- Is this something that can be done?
- If yes, is it something that SHOULD be done, or is there a better way to accomplish what I am trying to do?
- 这是可以做到的吗?
- 如果是,这是应该做的事情,还是有更好的方法来完成我想要做的事情?
Thanks
谢谢
回答by Igor Soloydenko
You can do the processing in your GetData's code, within the map
:
您可以在 GetData 的代码中进行处理map
:
// For RxJS v5
this.http
.get('http://server.name/api/GetData')
.map(result => {
const items = <any[]>result.json(); // could be SomeItem[] instead of any[]
items.forEach(item => item.ID = ...);
return items;
});
// For RxJS v6
this.http
.get('http://server.name/api/GetData')
.pipe(map(result => {
const items = <any[]>result.json(); // could be SomeItem[] instead of any[]
items.forEach(item => item.ID = ...);
return items;
}));
Then when you receive the object in your subscribe, the items should have the IDs assigned.
然后,当您在订阅中收到对象时,这些项目应该分配有 ID。
Here's the reference to the RxJs Observable's documentation: http://reactivex.io/rxjs/class/es6/Observable.js~Observable.html#instance-method-map
这是对 RxJs Observable 文档的参考:http://reactivex.io/rxjs/class/es6/Observable.js~Observable.html#instance-method-map
回答by gropapa
the idea is to :
这个想法是:
- get the result
- map the result to get the json only
- as your json is an array, produce an Observable for each data, then change its id and sent the data back
- gather them back in an array
- 得到结果
- 映射结果以仅获取 json
- 由于您的 json 是一个数组,因此为每个数据生成一个 Observable,然后更改其 id 并将数据发回
- 将它们收集回一个数组
the mergeMap (replaced flatMap in rxjs 5.5+) operator is used because an Observable operator always sends back an Observable, but since we create an Observable inside the result itself, it produces an Observable>, mergeMap removes an Observable layer. Hope this helps
使用 mergeMap(在 rxjs 5.5+ 中替换 flatMap)操作符是因为 Observable 操作符总是发回一个 Observable,但是由于我们在结果本身内部创建了一个 Observable,它产生了一个 Observable>,mergeMap 删除了一个 Observable 层。希望这可以帮助
GetData():Observable<WhateverWithIDInside[]> {
let data = this.http.get('http://server.name/api/GetData')
.map(res => res.json())
.mergeMap(dataArr =>
Observable.from(dataArr)
.map(data => {
data.ID = newID();
return data;
})
.toArray()
);
}