保存新属性会覆盖firebase对象

时间:2015-04-23 21:51:25

标签: angularjs firebase

我正在使用firebase和angular进行测验。在测验结束时,我想使用以下代码将新属性保存到users对象:

function saveTopscore() {
    var ref = new Firebase(CONSTANTS.FIREBASE_URL + 'users/' + User.user.$id + '/');
    var userObject = $firebaseObject(ref);
    userObject.topscore = User.totalCorrect;
    userObject.$save().then(function(ref) {
        console.log("worked");
    }, function(error) {
        console.log(error);
    });
}

它可以工作,但它也会覆盖用户对象的所有属性。因此,对象用于保存,如名称,用户名,电子邮件,密码等,但当我推动topscore时,它成为对象的唯一属性。为什么呢?

2 个答案:

答案 0 :(得分:8)

为什么在这里使用$firebaseObject?这仅在您将其三向绑定到Angular视图时才有用。如果您使用常规JavaScript代码,只需坚持使用Firebase的常规JavaScript SDK。

在这种情况下,只需:

ref.update({ topscore: User.totalCorrect });

答案 1 :(得分:1)

正如@Frank所说,使用JavaScript SDK。

我想澄清原始背景(使用$firebaseObject),以防其他人在将来引用此问题。

  • 原始症状正在发生,因为您正在设置对象的单个参数并在完全下载对象(及其已存在的子对象)之前保存它。
  • 因此,在您致电.$save()时,userObject(很可能)只会设置topscore参数,并且调用.$save()将有效删除所有Firebase参考中其他已存在的孩子。

您可以使用.$loaded()来避免这种情况,等到对象完全下载后再修改和/或更新它...

编辑但是,正如Intro to AngularFire指南所述,

  

应谨慎使用$loaded()方法,因为它只在初始加载后调用一次。除了调试之外,使用它通常是一种不好的做法。

如果您要忽略此警告并使用$loaded(),那么该实现可能如下所示:

注意 - ANTIPATTERN:这不是推荐的做法。

var ref = new Firebase(fbUrl + '/users/' + User.user.$id + '/');
var userObject = $firebaseObject(ref);
// wait until userObject has been downloaded, then modify & save it.
userObject.$loaded().then(function(){
  userObject.topscore = User.totalCorrect;
  userObject.$save().then(function(ref) {
      console.log("Saved");
  }, function(error) {
      console.log(error);
  });
});

弗兰克在对这个答案的评论中说,

  

“如果您在$loaded()(或$firebaseObject)之后直接使用$firebaseArray,那么您可能做错了。”