ValueChanges & SnapshotChanges, больше не получайте полные списки с Firebase AngularFire2

У нас возникли серьезные проблемы с недавними изменениями в том, как AngularFire рассматривает объекты/списки и ссылается на объекты в нашем приложении.

Главное, как старый AngularFireObject & AngularFireList работал по сравнению с новыми. Наше приложение было/сильно зависит от значения $key, поскольку мы сильно денормализовали (как рекомендовано).

Теперь документы используют пример карты, чтобы получить значение $key, но это не работает одинаково, и даже valueChanges(), похоже, не работает.

Я не совсем уверен, что теперь делать с изменениями.

Рассмотрим:

Старый путь

/* /items/
    a/{name: 'Dennis', city: 'Dallas'}
    b/{name: 'Katie', city: 'Austin'}
    c/{name: 'Will', city: 'Chicago'}
*/
let myAfList = this.af.list('path/to/items');
let itemsFirst, itemsSecond, itemsThird;

myAfList.subscribe(items => itemsFirst = items);

setTimeout(_ => myAfList.subscribe(items => itemsSecond = items), 1000);
setTimeout(_ => myAfList.subscribe(items => itemsThird = items), 2000);

/* Results for all three item arrays
    itemsFirst: [
        {name: 'Dennis', city: 'Dallas', $key: 'a'},
        {name: 'Katie', city: 'Austin', $key: 'b'}
        {name: 'Will', city: 'Chicago', $key: 'c'}
    ];
*/

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

Новый способ изменения значений:

let myAfList = this.af.list('path/to/items').valueChanges();
let itemsFirst, itemsSecond, itemsThird;

myAfList.subscribe(items => itemsFirst = items);

setTimeout(_ => myAfList.subscribe(items => itemsSecond = items), 1000);
setTimeout(_ => myAfList.subscribe(items => itemsThird = items), 2000);

/* Results for ONLY itemsFirst
    itemsFirst: [
        {name: 'Dennis', city: 'Dallas'},
        {name: 'Katie', city: 'Austin'}
        {name: 'Will', city: 'Chicago'}
    ];
*/

ItemsFirst, поскольку первая подписка правильно получает элементы. Остальные два элемента ничего не получают, но все трое подписываются на будущие изменения. Нет значения ключа.

С картой для $key

let myAfList = this.af.list('path/to/items').snapshotChanges()
            .map(actions => {
                return actions.map(action => {
                    const $key = action.payload.key;
                    const data = { $key, ...action.payload.val() };
                    return data;
                });
            });
let itemsFirst, itemsSecond, itemsThird;

myAfList.subscribe(items => itemsFirst = items);

setTimeout(_ => myAfList.subscribe(items => itemsSecond = items), 1000);
setTimeout(_ => myAfList.subscribe(items => itemsThird = items), 2000);

/* Results for ONLY itemsFirst
    itemsFirst: [
        {name: 'Dennis', city: 'Dallas', $key: a},
        {name: 'Katie', city: 'Austin', $key: b}
        {name: 'Will', city: 'Chicago', $key: c}
    ];
*/

$key теперь включен в список, но опять же он находится только в первом списке элементов...

Таким образом, быстрое наблюдение - это объекты, которые сейчас представляют собой простую оболочку вокруг основных ссылок на базовую базу, а valueChanges() необходимо переместить на вспомогательную сторону, например:

let myAfList = this.af.list('path/to/items');
myAfList.valueChanges().subscribe(items => itemsFirst = items);

Это работает! ура! Но как насчет ключа? ну, я должен снова и снова записывать функцию отображения. Или создайте мою собственную функцию, но она не на объекте proto, поэтому я должен добавить его в каждый файл, который я использую в нем...

Что мне не хватает? Каков правильный способ получить $key, всегда ли подписчики получают полные значения?

Есть ли лучший способ сделать это?

Ответ 1

Вы можете изучить эту возможность:

// Generate a reference to a new location and add some data using push()
var newPostRef = postsRef.push();

// Get the unique key generated by push()
var postId = newPostRef.key;

источник