У нас возникли серьезные проблемы с недавними изменениями в том, как 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, всегда ли подписчики получают полные значения?
Есть ли лучший способ сделать это?