#angular #observable
#angular #наблюдаемый
Вопрос:
У меня есть следующий метод:
getProject(name) {
this.ProjectName = name;
//Friendly URL to ID --> FIRST OBSERVABLE
this.af.database.object('/friendly_urls/' name).take(1).share().map((data) => {
//ID to data --> SECOND OBSERVABLE
this.af.database.object('/Project/' data.$value).take(1).map((ProjectData) => {
console.log("Received Project data");
this.ProjectData = ProjectData;
});
},
error => {
console.log(error);
/* TODO: Permission blocked page */
this.router.navigate(['']);
});
}
}
У меня есть 2 наблюдаемых объекта: первый наблюдаемый объект, который выполняется первым, и второй, который выполняется сразу после него.
Я пытался понять, как использовать это в моем случае, и не смог этого понять.
Как я могу выполнить эти наблюдаемые в серии без observable внутри observable?
Ответ №1:
Используйте switchMap
, чтобы взять значение из первого наблюдаемого и использовать его как начальное значение для 2-го наблюдаемого. Сначала вы настраиваете (составляете) поток:
projectData$ = this.af.database.object('/friendly_urls/' name).share().switchMap(
data => this.af.database.object('/Project/' data.$value)
).take(1);
Затем, когда вы хотите извлечь данные, просто subscribe
:
projectData$.subscribe(
projectData => this.ProjectData = projectData,
error => console.log(error);
)
Комментарии:
1. Привет, спасибо! Но если я подпишусь на
projectData$
,ProjectData
переменная будет наблюдаемойthis.af.database.object('/Project/' data.$value)
, а не фактической информацией, которая мне нужна (которая является подпиской на это наблюдаемое)2. Это приводит к тому, что мне нужно сделать 2 подписки, как и раньше, одну за другой.
ProjectData.subscribe((data) => { this.RealProjectData = data } );
3. @Elikos Я знаю, что
database.object
возвращает наблюдаемое. Вот почему я используюswitchMap
вместоmap
. Вы уже пробовали мое решение, и оно не удалось, или вы делаете прогноз о том, что произойдет?4. Прошу прощения! Использовал
.map
все долгое время. Это работает потрясающе! Спасибо вам.5. Можете ли вы опубликовать пример, как сделать то же самое с 3 наблюдаемыми объектами, зависящими друг от друга?
Ответ №2:
Вы должны использовать оператор static concat
, который подписывается на первый наблюдаемый объект, а после завершения — на второй.
let obs1 = this.af.database.object('/friendly_urls/' name).map(data => data.$value);
let obs2 = this.af.database.object('/Project/' data.$value).map(project => this.ProjectData = project);
let concatenatedObservables = Observable.concat(obs1, obs2);
concatenatedObservables.subscribe();
Подробнее об этом здесьhttp://reactivex.io/rxjs/class/es6/Observable.js ~Observable.html#экземпляр-метод-объединение
Комментарии:
1. Это не сработает, поскольку автор использует
data
возвращенные из obs 1 данные в качестве входных данных для obs 2.concat
запускает их в независимых контекстах.