2015-04-23 87 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的全部內容。 –