Форк свързва две наблюдаеми на 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()? Имам подобен въпрос, но трябва да запазя връзката с firsbase: stackoverflow.com/questions/41785252/ - person Hugh Hou; 22.01.2017