2014-09-24 46 views
0

我正在使用Angular.js和Firebase API從this tutorial開始執行步驟。無法從指令angularjs中的Firebase中獲取數據

我已經在我的指導文件中創建一個指令「滑」,這裏是代碼:

.directive('slider', function() 
{ 
    return { 
     restrict: 'E', 
     replace: true, 
     link: function(scope, elem, attrs) { 
      scope.currentIndex = 0; // Initially the index is at the first slide 

      scope.next = function() 
      { 
       scope.currentIndex < scope.challenges.length - 1 ? scope.currentIndex++ : scope.currentIndex = 0; 
      }; 

      scope.prev = function() 
      { 
       scope.currentIndex > 0 ? scope.currentIndex-- : scope.currentIndex = scope.challenges.length - 1; 
      }; 

      scope.$watch('currentIndex', function() 
      { 
       scope.challenges.forEach(function(challenge) 
       { 
        challenge.visible = false; // make every challenge invisible 
       }); 

       scope.challenges[scope.currentIndex].visible = true; // make the current challenge visible 
      }); 
     }, 
     template: '<div></div>' 
    }; 

我沒有分離範圍,因爲你看到的,所以它應該從父scope.challenges,但它來自未定義的值,而不是來自Firebase的數據。

這樣做的foreach不確定它拋出一個錯誤: 類型錯誤:無法讀取屬性未定義

「的forEach」我花了像3小時試圖理解範圍,解決方案會如此回報。 非常感謝。

+0

你可以分享創建挑戰的代碼嗎?你提到了firebase,所以我想有一些異步操作發生? – Kato 2014-09-24 20:45:54

+0

Alternative angular.forEach(scope.challenges,function(challenge){challenge.visible = false}); – DeadCalimero 2014-09-24 21:03:55

+0

@Kato in controller我有'$ scope.findAll = function(){$ scope.challenges = Challenge.findAll(); };'它只取得Firebase的所有結果。 – 2014-09-24 21:12:25

回答

0

我不知道我是否missunderstood,但:

var currentIndexChangeHandler = function(newValue, oldValue) { 
    scope.challenges.forEach(function(challenge) { 
     //do something 
    } 
} 
scope.$watch('currentIndex', currentIndexChangeHandler); 

會招來說: 「currentIndexChangeHandler」 將在第一個運行的觸發(參見:$watch is triggered directly after init, why?),當「scope.challenges「仍未定義。

如果(newValue!= oldValue)「colud」hack「this」first run「with」「,但我認爲這不是重點。 其他問題是,當您迭代「scope.challenges」時,它是未定義的,因爲它的值應該是異步收到的。可以使用「if(布爾型(範圍挑戰))」來解決,但這不是正確的方法。

我認爲真正的問題是您正在使用異步數據。

¿什麼值返回Challenge.findAll()? ¿也許是一個承諾?這樣你應該使用:

Challenge.findAll().then(function(challenges){ 
    $scope.challenges = challenges; 
} 

我用我的消化重構你的代碼。那是行爲嗎,你在假裝什麼?

http://jsfiddle.net/rizome/uqtaoLne/

UPDATE:

使用火力地堡和$火力點(參見:https://www.firebase.com/docs/web/libraries/angular/api.html#angularfire-firebase

$火力」 AngularJS wraper具有比小提琴編碼上述類似的行爲,但你應該使用「$ firebase」API來獲得承諾。 (這段代碼代表你的回購服務中的代碼,並控制以及內部)

var firebaseResource = $firebase(new Firebase(YOUR_DATA_URL)); 
var firebaseSyncArray = firebaseResource.$asArray(); //it is still empty 
var loadedArrayPromise = firebaseSyncArray.$loaded(); //promise with the array when loaded 
var loadedArrayPromise.then(function (challenges) { 
     $scope.challenges = challenges; //now, you can set $scope.challenges 
}); 
1

@rizome非常感謝你的回答,這是非常有用的。

Firebase API直接返回承諾,所以您不必這樣做。

最後我解決這個問題,更新「angularfire」到V0.8和驗證碼:

// Controller code 
Challenge.findAll().$asArray().$loaded().then(function(challenges) 
{ 
    $scope.challenges = challenges; 
}); 

基本上它是等到挑戰是準備來分配。

來自firebase的article真的是一個很好的解決它的資源。

+0

AngularFire目前在0.8.2上。在0.8和最新版本之間有一些錯誤修復。 – Kato 2014-09-25 14:18:25

+0

相關提示@Kato我將更新至最新版本 – 2014-09-25 14:40:31

相關問題