2015-04-23 86 views
2

我正在使用firebase和angular进行测验。在测验结束时,我要保存一个新的属性到用户对象使用此代码:保存新属性覆盖firebase对象

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); 
    }); 
} 

和它的作品,但它也覆盖用户对象的所有属性。所以这个对象用来保存名称,用户名,电子邮件,密码等,但是当我推入顶端时,它就成为对象的唯一属性。为什么?

回答

8

为什么在这里使用$firebaseObject?这只有在你将它绑定到一个Angular视图的时候才有用。如果您使用的是常规JavaScript代码,只需使用Firebase的常规JavaScript SDK即可。

在这种情况下,只是做:

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

谢谢你的工作!我这样做是因为它在api文档中这么说。但这很容易。 – idontknow

+5

我相当积极的API文档不会说使用$ bindTo或任何AngularFire绑定,如果你不打算同步数据在视图或服务中使用。 (提示:我写了他们) – Kato

1

正如@Frank说,使用JavaScript SDK。

我想澄清原始上下文(使用$firebaseObject),以防其他人在将来提到此问题时使用。

  • 原始症状的发生是因为您要设置对象的单个参数并在对象(及其已存在的子对象)完全下载之前将其保存。
  • 因此,当您拨打.$save()时,userObject将(很有可能)仅设置其参数topscore,并且调用.$save()将有效地移除Firebase中的所有其他预先存在的子级。

你可能避免这种使用.$loaded()等到对象已修改和/或更新之前完全下载...

编辑:然而,随着Intro to AngularFire指导各国,

$loaded()方法应小心使用,因为它只在初始加载后调用一次。将它用于除调试之外的任何事情通常都是不好的做法。

如果你忽略此警告并使用$loaded()无论如何,该实现看起来是这样的:

注 - 反模式:这不是一个推荐的做法。

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),你可能做错了什么。”

+0

嘿思南。你的方法也适用。但是我已经开始使用一个规则:“如果你直接在'$ firebaseObject'(或$ firebaseArray')之后使用'$ loaded()',那么你可能做错了什么。我们看到'$ loaded()'的使用太​​多了,我将在可能的地方说明为什么人们不需要它。 ;-)尽管如此,你的解决方案绝对可行。 –

+0

嗨,弗兰克。这是一个伟大的观点,这是一个伟大的规则!感谢澄清。我希望解释下载数据的过程。我现在在[Intro to AngularFire](https://www.firebase.com/docs/web/libraries/angular/guide/intro-to-angularfire.html#section-async-intro)中看到使用'$ loaded( )'除了调试之外,被认为是不好的做法。如果'$ loaded()'被过度使用,那么解决这个问题的计划是什么?我认为将功能反模式列表作为参考是非常棒的。 –

+1

您发现的新文档是我们尝试更加明确的一种方法。但它仍然很棘手。我们经常告诉人们只需将'firebaseObject'绑定到他们视图中的元素即可。它会用很少的代码完成他们试图做的事(调试/检索数据),这就是AngularFire的全部内容。 –