【发布时间】:2017-06-14 15:27:56
【问题描述】:
我试图弄清楚在 Angular 中加入 Observables 的基础知识。我找到了几个示例,但似乎无法弄清楚如何让它有效地工作。
我有以下数据结构:
- courses
- $courseid1
- $courseid2
- $courseid3
- ...
- teachers
- $teacherid1
- $teacherid2
- $teacherid3
- ...
- teachersPerCourse
- $courseid1
- $teacherid1 : true
- $teacherid2 : true
- $courseid2
- $teacherid1 : true
- $courseid3
- $teacherid3 : true
- ...
现在我正在使用以下函数来检索带有 slug 的课程:
getFullCourseBySlug(slug:string) {
return this.db.list('academy/courses', {
query: {
orderByChild: 'slug',
equalTo: slug
}
}).map((courses) => courses[0]);
}
现在我希望将一组教师映射到课程对象,以便最终得到一个发出如下内容的可观察对象:
{
title: ...,
slug: ...,
teachers: {
$teacherid1: {
firstname: ...,
lastname: ...,
etc ... },
$teacherid2: {
firstname: ...,
lastname: ...,
etc ... }
}
}
我在其他地方也有同样的工作原理,但是我必须在 map 函数中使用订阅,或者在 Observables 中使用 Observables。例如:
getCoursesPerCategory(categoryid:string):Observable<Course[]> {
return this.db.list(`academy/coursesPerCategory/${categoryid}`).map(courses => {
courses.map(course => {
this.db.object(`academy/courses/${course.$key}`).subscribe((data) => {
course.$value = data;
});
return course;
});
return courses;
});
}
如果有人可以帮助我举例说明如何更有效地做到这一点,我将不胜感激!
更新:
我已经设法让它工作,但我仍然无法摆脱嵌套的 Observables,这意味着我必须使用三重异步管道(这可能不是最佳实践:P)我尝试过按照建议使用 flatMap ,但还不知道该怎么做。我现在拥有的:
getFullCourseBySlug(slug:string): Observable<any> {
return this.db.list('academy/courses', {
query: {
orderByChild: 'slug',
equalTo: slug
}
}).map(courses => courses[0]).switchMap(course => {
course.teachers = this.db.list(`academy/teachersPerCourse/${course.$key}`)
.map(teachers => {
teachers.map(teacher => {
teacher.$value = this.db.object(`academy/teachers/${teacher.$key}`);
});
return teachers;
});
return Observable.of(course);
});
}
使用以下模板:
{{ (course | async)?.title }}
<ul>
<li *ngFor="let teacher of ((course | async)?.teachers ) | async">
{{ (teacher.$value | async)?.firstname }}
</li>
</ul>
更新 2:
查看我的解决方案的答案
【问题讨论】:
标签: angular dictionary rxjs observable angularfire2