ValueChanges&SnapshotChanges,不再使用Firebase AngularFire2获取完整列表

Den*_*lek 11 rxjs angularjs firebase angularfire2 angular2-observables

最近AngularFire如何处理对象/列表以及引用整个应用程序中的对象,我们遇到了一些严重的问题.

主要的是旧的AngularFireObject & AngularFireList工作与新的相比.我们的应用程序高度依赖于$key价值,因为我们非常规范化(如推荐).

现在,文档使用一个map示例来获取$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'}
    ];
*/
Run Code Online (Sandbox Code Playgroud)

所有三个订阅都正确获取完整的项目数组,并设置为收听未来的更改

价值变化的新方法:

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'}
    ];
*/
Run Code Online (Sandbox Code Playgroud)

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}
    ];
*/
Run Code Online (Sandbox Code Playgroud)

$key 现在在列表中,但它再次只在第一个项目列表上...

所以快速观察一下,对象现在是围绕核心firebase引用的非常简单的包装器,而valueChanges()需要移动到子端,如:

let myAfList = this.af.list('path/to/items');
myAfList.valueChanges().subscribe(items => itemsFirst = items);
Run Code Online (Sandbox Code Playgroud)

这有效!好极了!但关键呢?好吧,我必须一遍又一遍地写出地图功能.或者创建我自己的函数,但它不在对象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;
Run Code Online (Sandbox Code Playgroud)

来源

  • 那么“update”和“push”怎么样,我们怎样才能简单地获取密钥呢? (2认同)