我正在使用Angular2开始我的项目,开发人员似乎推荐RXJS Observable而不是Promises。
我已经实现从服务器检索元素列表(史诗)。 但是如何通过使用例如id来过滤元素?
以下代码是从我的应用程序中提取的,现在显示最终的工作解决方案。我们希望它可以帮到某人。
@Injectable()
export class EpicService {
private url = CONFIG.SERVER + '/app/'; // URL to web API
constructor(private http:Http) {}
private extractData(res:Response) {
let body = res.json();
return body;
}
getEpics():Observable<Epic[]> {
return this.http.get(this.url + "getEpics")
.map(this.extractData)
.catch(this.handleError);
}
getEpic(id:string): Observable<Epic> {
return this.getEpics()
.map(epics => epics.filter(epic => epic.id === id)[0]);
}
}
export class EpicComponent {
errorMessage:string;
epics:Epic[];
epic:Epic;
constructor(
private requirementService:EpicService) {
}
getEpics() {
this.requirementService.getEpics()
.subscribe(
epics => this.epics = epics,
error => this.errorMessage = <any>error);
}
// actually this should be eventually in another component
getEpic(id:string) {
this.requirementService.getEpic(id)
.subscribe(
epic => this.epic = epic,
error => this.errorMessage = <any>error);
}
}
export class Epic {
id: string;
name: string;
}
提前感谢您的帮助。
答案 0 :(得分:58)
您需要过滤实际数组,而不是过滤掉它周围的observable。
因此,您可以将Observable的内容(Epic[]
)映射到已过滤的Epic
。
getEpic(id: string): Observable<Epic> {
return this.getEpics()
.map(epics => epics.filter(epic => epic.id === id)[0]);
}
然后你可以subscribe
到getEpic
并随意做任何事情。
答案 1 :(得分:26)
您可以使用flatMap
的{{1}}和filter
方法代替Observable
中的JS数组过滤方法来执行此操作。类似的东西:
map
this.getEpics()
.flatMap((data) => data.epics) // [{id: 1}, {id: 4}, {id: 3}, ..., {id: N}]
.filter((epic) => epic.id === id) // checks {id: 1}, then {id: 2}, etc
.subscribe((result) => ...); // do something epic!!!
将提供用于过滤的单数索引,然后您可以继续使用结果接下来发生的任何事情。
如果TypeScript抛出错误,指示您无法比较字符串和数字,无论您在过滤器中使用flatMap
,只需在过滤器中==
之前添加+
,根据Angular文档:
epic.id
示例:强>
https://stackblitz.com/edit/angular-9ehje5?file=src%2Fapp%2Fapp.component.ts
答案 2 :(得分:1)
带有修复的原始答案:
Observables
很懒惰。您必须致电subscribe
告诉observable
发送请求。
getEpic(id:number) {
return this.getEpics()
.filter(epic => epic.id === id)
.subscribe(x=>...);
}
更新到Rxjs 6:
import {filter} from 'rxjs/operators';
getEpic(id:number) {
return this.getEpics()
.pipe(filter(epic => epic.id === id))
.subscribe(x=>...);
}
答案 3 :(得分:0)
您必须在newUser.Roles.Add(new IdentityUserRole {UserId = newUser.Id, RoleId = "your role id"});
订阅才能获取数据,因为http调用在JavaScript中是异步的。
Observable
您可以像这样调用该方法:
getEpic(id: number, callback: (epic: Epic) => void) {
this.getEpics().subscribe(
epics: Array<Epic> => {
let epic: Epic = epics.filter(epic => epic.id === id)[0];
callback(epic);
}
);
}