2016-09-04 4 views
4

Я использую angular2fire. Я спрашиваю и пытаюсь получить все туры из города.Вилка соединяется с двумя наблюдаемыми объектами базы

getAllTours(cityId) { 
    return this.af.database.list(`/cities/${cityId}/tours`) 
     .map((tours): any => { 
      tours.map((tour: any) => { 
       tour.tour = this.af.database.object(`/tours/${tour.$key}/tours`) 
      }); 
      return tours; 
     }) 
} 

Если я console.log объект тура, я получаю массив "FirebaseObjectObservable".

Мне нужно пройти весь FirebaseObjectObservable, чтобы получить фактические данные.

Мне было интересно, могу ли я использовать forkJoin все наблюдаемые и получать выходные данные в виде массива с одной подписной функцией.

Это правильный подход.

Я знаю, что могу сделать асинхронную трубку во всем массиве наблюдателей, но я хотел бы получить данные внутри контроллера, а затем выполнить некоторую обработку перед ее показанным в представлении, поэтому асинхронный канал на самом деле не самый лучший вариант для меня.

ответ

7

Да, forkJoin может быть использован для получения данных для внутренних наблюдаемых:

getAllTours (cityId) { 
    return this.af.database 
     .list(`/cities/${cityId}/tours`) 
     .mergeMap((tours) => { 

      // The array of tours is going to be mapped to an observable, 
      // so mergeMap is used. 

      return Observable.forkJoin(

       // Map the tours to the array of observables that are to 
       // be joined. Note that forkJoin requires the observables 
       // to complete, so first is used. 

       tours.map((tour) => this.af.database 
        .object(`/tours/${tour.$key}/tours`) 
        .first() 
       ), 

       // Use forkJoin's results selector to match up the result 
       // values with the tours. 

       (...values) => { 
        tours.forEach((tour, index) => { tour.tour = values[index]; }); 
        return tours; 
       } 
      ); 
     }); 
} 

ли не использовать forkJoin правильный подход будет зависеть от ваших требований.

С приведенным выше кодом наблюдаемый, возвращаемый getAllTours, не будет выдавать значение до тех пор, пока все внутренние наблюдаемые не будут завершены, то есть до тех пор, пока каждый из туров города не будет поднят. Это может повлиять на воспринимается производительность - если есть информация в /cities/${cityId}/tours, которая может быть показана до того, как информация в /tours/${tour.$key}/tours будет просмотрена, вы не сможете ее показать. Точно так же вы не сможете показывать экскурсии по городу по мере поступления результатов.

Использование forkJoin упрощает работу с реализацией, но это может сделать интерфейс более медленным. (Тем не менее, поэтапное обновление пользовательского интерфейса может быть чем-то, что вам не нужно.)

Обратите внимание, что если вам нужно выполнить некоторую обработку в каждом из туров города, прежде чем он будет показан в представлении, вы можете быть в состоянии для выполнения указанной обработки на наблюдаемых в коде в вашем вопросе. Например, с помощью функции getAllTours:

observable = getAllTours(someCityId); 
observable.map((tours) => { 

    tours.forEach((tour) => { 

     // With your function, tour.tour is an observable, so map 
     // could be used to process the values. 

     tour.tour = tour.tour.map((value) => { 

      // Do some processing here with the value. 
     }) 

     // And, if you are not interested in dynamic updates, you could 
     // call first. 

     .first(); 
    }); 
    return tours; 
}); 

Вы можете затем использовать async трубу в шаблоне, и он будет получать ваши обработанные туры.

+0

Это работает, но я хотел знать, подходит ли мое мышление, будет ли это медленнее, если у меня будет много записей? – harikrish

+0

Я только что прочитал ваш комментарий. Завтра я добавлю некоторые заметки о производительности; уже поздно здесь. – cartant

+0

Не стоит беспокоиться, спасибо большое :) – harikrish

Смежные вопросы