2013-12-15 36 views
1

對不起,這有點讓我有點瘋狂:使用AngularFire v2獲取關鍵值有點清晰嗎?

假設我想在加載時獲得一個項目的「title」和「.priority」鍵值。

首先,讓我們看到的每一件事情是如何佈局:

$scope.items = $firebase(new Firebase("https://****.firebaseio.com")); 

$scope.items.$on('loaded', function() { 

console.log($scope.items); 

}); 

隨着我們得到:

> Object {$bind: function, $add: function, $save: function, $set: function, $remove: function…} 
    > $add: function (item, cb) { 
    > $bind: function (scope, name) { 
    > $child: function (key) { 
    > $getIndex: function() { 
    > $on: function (type, callback) { 
    > $remove: function (key) { 
    > $save: function (key) { 
    > $set: function (newValue) { 

    > this is my item: Object 
      $$hashKey: "012" 
      $id: "this is my item" 
      $priority: 2884707 
      title: "this is the title of my item" 
      __proto__: Object 


    > __proto__: Object 

看起來不錯,讓我們試着搶$優先級:

console.log($scope.items.$child('$priority')); 

糟糕:

Uncaught Error: Firebase.child failed: First argument was an invalid path: "$priority". Paths must be non-empty strings and can't contain ".", "#", "$", "[", or "]" 

好,我們將跳過,就目前而言,只是嘗試標題:

console.log($scope.items.$child('title')); 

> Object {$bind: function, $add: function, $save: function, $set: function, $remove: function…} 
    > $add: function (item, cb) { 
    > $bind: function (scope, name) { 
    > $child: function (key) { 
    > $getIndex: function() { 
    > $on: function (type, callback) { 
    > $remove: function (key) { 
    > $save: function (key) { 
    > $set: function (newValue) { 
    > __proto__: Object 

沒有標題。

好吧,讓我們嘗試用不同的方式:

var firstItem = $scope.items.$getIndex()[0]; //returns $ids in order of priority 
    console.log($scope.items.$child(firstItem)); 

    > Object {$bind: function, $add: function, $save: function, $set: function, $remove: function…} 
     > $add: function (item, cb) { 
     > $bind: function (scope, name) { 
     > $child: function (key) { 
     > $getIndex: function() { 
     > $on: function (type, callback) { 
     > $remove: function (key) { 
     > $save: function (key) { 
     > $set: function (newValue) { 
       title: "this is the title of my item" 
     > __proto__: Object 

但是現在有沒有優先級!在電腦前的時間

廚房水槽宣誓:

console.log($scope.items.title); 

    > undefined 

console.log($scope.items[0].title); 

    > Uncaught TypeError: Cannot read property 'title' of undefined 

    console.log(Object.keys($scope.items));  

    > ["$bind", "$add", "$save", "$set", "$remove", "$child", "$on", "$getIndex"] 

我缺少什麼?我可以設法通過做兩次U形轉彎來獲得'標題'(弄清楚該項目的$ id使用'$ getIndex()',抓住第n個項目,然後使用'$ child()'進行另一個調用),但即使如此也不適用於優先權。有沒有更簡單的方法從AngularFire v2中獲取關鍵值?或以任何方式獲得優先權?

+0

這裏有兩件事。首先是$ child會得到一個記錄的關鍵字,所以你想嘗試一下'$ scope.items。$ child('record1')。$ priority'。其次,請嘗試升級到[最新/官方0.5版本](https://cdn.firebase.com/libs/angularfire/0.5.0/angularfire.js),因爲Anant只是做了一些適用於這裏的修復。如果這沒有幫助,請回報您的發現。 – Kato

+0

這是我連接到的版本和'$ scope.items。$ child('record1')。$ priority'給我'undefined',這是正確的,因爲當'console.log($ scope.items。使用$ child('record1'))',就像在我的「好吧,讓我們嘗試一種不同的方式」的例子。如果它應該那麼這可能是一個錯誤。 – jthomasbailey

+0

我還不清楚。問題的關鍵是,$子如同Firebase.child()一樣運行。 angularFire轉到Firebase,在當前路徑上調用.child(),併爲該子路徑返回一個新的$ firebase對象。因此,您不能要求$ child('$ priority'),因爲這不是有效的Firebase密鑰。這不是從對象獲取子鍵的方式,而是一種新的對Firebase路徑的同步引用。因此子鍵可以通過'$ scope.items ['$ priority']'或類似的方式獲得(我在上面寫錯了 - 對不起)。 – Kato

回答

5

我相信我是/遇到同樣的問題。希望這與你的經驗有關。即:

$scope.items = $firebase(new Firebase("https://xxxxxx.firebaseio.com")); 
$scope.items.$on('loaded', function() { 
    console.log($scope.items['some key']); // this writes undefined to console 
}); 

我注意到的是,這其實確實工作如果我不靠loaded事件。 E.g在HTML:

<a href="#" data-ng-click="logItem()">click me</a> 

,並在JS:

$scope.items = $firebase(new Firebase("https://xxxxxx.firebaseio.com")); 
$scope.logItem = function() { 
    console.log($scope.items['some key']); // this works 
} 

點擊預期 「點擊我」 鏈接登錄我的項目到控制檯。

感覺像loaded時間的集合沒有完全填充來自Firebase的基礎項目。

+0

啊哈!把它放在$超時也可以! – jthomasbailey

+1

順便說一句,我現在使用[本答案](http://stackoverflow.com/a/20610932/2478447)​​中定義的模式。原來的firebase數據沒有在'loaded'時間填充,它作爲回調函數的參數傳遞,所以如果你喜歡,你可以這樣訪問它。 – mlenner

3

正如您所指出的,您的示例有點零碎,也沒有您的數據結構的例子。因此,想要了解您想要完成的內容有點困難。我將在下面對所有這些事情做出一些假設,然後相應地提供一個工作示例。如果這不能回答這個問題,那麼它可能會幫助我們深入挖掘並找到您需要的確切用例。

假設,對於初學者來說,我們必須在kato.firebaseio.com/users用戶的列表,每個就像是一個對象,因此:

/users/:id/name 
/users/:id/email 
/users/:id/favorite_dessert 

現在,讓我們假設我要打具有以下angularCode那些工作:

<ul> 
    <li ng-repeat="user in users">{{user.name}} really likes {{user.favorite_dessert}}</li> 
</ul> 

在我的控制,我可以把這樣的事情:

var fbRef = new Firebase('https://kato.firebaseio.com/users'); 
$scope.users = $firebase(fbRef); 

現在它們會自動出現在我的HTML代碼中。

現在,讓我們假設當點擊這些用戶之一,我希望得到一個雙向綁定,它可以在一個表編輯是這樣的:

<form ng-controller="EditUserController"> 
     <input ng-model="user.name" type="text" /> 
     <input ng-model="user.email" type="text" /> 
     <input ng-model="user.favorite_dessert" type="text" /> 
</form> 

裏面EditUserController我能獲得用戶如下:

var fbRef = new Firebase('https://kato.firebaseio.com/users/'+user_id); 
$firebase(fbRef).$bind($scope, 'user'); 

或者我可以用$child像這樣(純粹是爲了演示$孩子的使用,沒有必要):

var fbRef = new Firebase('https://kato.firebaseio.com/users'); 
// $child gives a new $firebase object! not a ref to a hash key! 
$firebase(fbRef).$child(user_id).$bind($scope, 'user'); 

如果我想訪問此類數據編程我的控制器內,我能做到這一點,像這樣:

var fbRef = new Firebase('https://kato.firebaseio.com/users'); 
var usersRef = $firebase(fbRef); 
var userId = 'kato'; 
usersRef.$on('loaded', function() { 
    if(usersRef.hasOwnProperty(userId)) { 
     // note that we just grab it by key; not $child! 
     var userRecord = usersRef[userId]; 
     console.log(userId + ' was found, name is ' + userRecord.name + ' and priority is ' + userRecord['$priority']); 
    } 

}); 
+0

對不起加藤 - 我花了幾個小時試圖重新創建這個,但是'myRef [blah]'和'myRef.blah'總是返回undefined。 'myRef。$ child('blah')'起作用但是有限,因爲像你說的那樣它不能用'$'返回任何東西。我不知道這與AngularFire有什麼關係,我會把它交給他們的github,看看他們對缺少的優先級的評價。但是這裏有一個特性請求:'startAt(fbRef.getIndex()[100])'(是的,這是關於嘗試startAt()firebase中的第n個項目!我設置的方式不是很容易搞清楚$ id和$ priority)一如既往! – jthomasbailey

4

$child方法只能用於創建一個新 AngularFire參考。調用$child與調用$firebase(new Firebase(parentULR + "/childName"))相同。在你的例子,如果你正在嘗試做的是獲得給定對象的$prioritytitle,你可以簡單地做:

$scope.items = $firebase(new Firebase("https://****.firebaseio.com")); 
$scope.items.$on('loaded', function() { 
    var item = $scope.items['your-item-id']; 
    console.log(item['$priority']); 
    console.log(item.title); 
}); 

如果你不知道你的項目的ID,你可以遍歷如果您願意,可以在$scope.items對象中找到它。

+0

謝謝,但這是當我這樣做時發生的事情:http://imgur.com/a/mXePx(抱歉的形象,是最快的方式向你展示,我明顯地編輯了Firebase地址,但這是它的其他內容) 。 – jthomasbailey

+0

這很奇怪,你可以console.log($ scope.stories)?它應該有一堆對象。 – Anant

+0

mlenner在那裏發現了它,顯然它還沒有準備就緒('loaded'),所以我只需要使用一點點$超時。 – jthomasbailey