AngularFire:如何通过扩展服务并使用$$更新的私有方法来更新$ firebaseArray

时间:2016-07-23 08:01:55

标签: firebase-realtime-database angularfire denormalized

我的数据库中有两个单独的帖子和作者列表,每个帖子包含一个authorId来引用相应的作者。

以下方法通过系统地包含每个帖子的作者姓名来帮助我检索整个帖子列表:

app.factory('NormalizedPosts', function($firebaseArray, FirebaseFactory) {
    var PostsWithAuthors = $firebaseArray.$extend({

        // override $$added to include author name
        $$added: function(snap) {
            var record = $firebaseArray.prototype.$$added.call(this, snap);

            FirebaseFactory.$getAuthorId( record.authorId ).$loaded(function( authorData ) {
                record.authorData = authorData;
            });

            return record;
        },

        // ????????
        $$updated: function(snap) { 

            var rec = $firebaseArray.prototype.$$updated.call(this, snap); 
            var updatedRecord = this.$getRecord(snap.key()); 

            FirebaseFactory.$getAuthorId( updatedRecord.authorId )
            .$loaded(function( authorData ) { 
                rec.authorData = authorData; 
            }); 

        return rec; 

        }

    });

    return PostsWithAuthors;
});

PS:FirebaseFactory只是firebase方法的包装器。

然后我打电话给

var list = new NormalizedPosts ( new Firebase(FBURL).child("posts") ); 

在我的控制器中获取完整列表。这很有效。

我对应该进入$$更新方法的内容感到头疼:当添加新帖子时,列表会按预期更新(通过$$添加方法)。但是当Post数据发生变化时(例如帖子标题),我的列表不会更新,因为我目前在$$更新方法中返回false。

问题:$$更新方法应该采用什么方式,以便当发布数据发生变化时,我的列表会相应更新(并进一步返回作者姓名!)。感谢

2 个答案:

答案 0 :(得分:0)

我认为你经历了太多的循环来完成一些简单的工作。

如果作者的姓名是""的一部分文章比你应该保存它:

{
    "articles": {
        "firebase-uniq-id-1": {
            "title": "My Writing Process",
            "published": "2016-01-01",
            "author": {
                "firebase-uniq-id-2": "Ernest Hemingway"
            }
        }
    },
    "authors": {
        "firebase-uniq-id-2": {
            "name": "Ernest Hemingway",
            "born": "1899-07-21",
            "whatever": "Some Data"
        }
    }
}

如果您想要显示有关作者的其他详细信息,请抓取它。

编辑: 如果您仍然希望使用扩展程序选项,我相信您唯一遗漏的是使用updateRecord扩展rec

FirebaseFactory.$getAuthorId( updatedRecord.authorId )
    .$loaded(function( authorData ) { 
        updatedRecord.authorData = authorData; 
        angular.extend(updatedRecord, snap.val());
    });

此外,在$$updated中,如果记录发生了变化,你需要返回一个布尔值,而不是记录本身。

请注意,如果你走这条路,就不应该使用$save()的默认$firebaseArray方法,因为它也会保存完整的authorData

答案 1 :(得分:0)

$$updated: function(snap) { 

    // boolean for the $$updated method
    var rec = $firebaseArray.prototype.$$updated.call(this, snap); 

    // existing record as per this
    var existingRecord = this.$getRecord(snap.key()); 

    // record as per FB database
    var updatedRecord = snap.val();

    if ( rec ) {

        FirebaseFactory.$getAuthorId( updatedRecord.authorId )
        .$loaded(function( authorData ) { 
            updatedRecord.authorData = authorData;
            angular.extend(existingRecord, updatedRecord);
        }); 

    } // end if loop

    return rec; 

}