Вилка соединяет две наблюдаемые базы данных firebase

Я использую 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 все наблюдаемые и получить результат в виде массива с одной функцией подписки.

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

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


person harikrish    schedule 04.09.2016    source источник


Ответы (1)


Да, 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 в шаблоне, и он будет получать ваши обработанные туры.

person cartant    schedule 05.09.2016
comment
Это работает, но я хотел знать, правильно ли я думаю, замедлит ли это систему, если у меня будет много записей? - person harikrish; 05.09.2016
comment
Я только что прочитал ваш комментарий. Завтра я добавлю к ответу несколько примечаний к производительности; уже поздно здесь. - person cartant; 05.09.2016
comment
Не беспокойтесь, большое спасибо :) - person harikrish; 05.09.2016
comment
Обновлен ответ на вопрос: является ли forkJoin правильным подходом. - person cartant; 06.09.2016
comment
Есть ли способ использовать joinfork без complete / first ()? У меня есть аналогичный вопрос, но мне нужно сохранить соединение с первой базой: stackoverflow.com/questions/41785252/ - person Hugh Hou; 22.01.2017