[英]Cannot get data from firebase in directive angularjs
I'm doing a slider following the steps from this tutorial using Angular.js and Firebase API. 我正在使用Angular.js和Firebase API按照本教程中的步骤进行操作。
I have created a directive 'slider' in my directive file, here is the code: 我在指令文件中创建了指令“ slider”,下面是代码:
.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>'
};
I have no isolate scope, as you see, so it should take scope.challenges from parent, but it comes as undefined value instead of the data from Firebase. 如您所见,我没有隔离范围,因此它应该采用来自父级的scope.challenges,但它是未定义的值而不是Firebase的数据。
So doing forEach of undefined it throws an error: TypeError: Cannot read property 'forEach' of undefined 因此,执行未定义的forEach会引发错误: TypeError:无法读取未定义的属性'forEach'
I spent like 3 hour trying to understand scopes, a solution will be so rewarding. 我花了大约3个小时来尝试了解范围,因此解决方案将非常有益。 Thank you very much.
非常感谢你。
@rizome thank you very much for your answer, it was really useful. @rizome非常感谢您的回答,它非常有用。
Firebase API returns directly a promise, so you don't have to do so. Firebase API直接返回承诺,因此您不必这样做。
Finally I resolve it, updating 'angularfire' to v0.8 and this code: 最后,我将其解决,将“ angularfire”更新为v0.8和以下代码:
// Controller code
Challenge.findAll().$asArray().$loaded().then(function(challenges)
{
$scope.challenges = challenges;
});
Basically what it does is wait till challenges are ready to assign. 基本上,它的工作是等到准备好分配挑战。
This article from firebase was really a good resource to solve it. firebase的这篇文章确实是解决该问题的好资源。
I don't know if I missunderstood, but: 我不知道我是否误会了,但是:
var currentIndexChangeHandler = function(newValue, oldValue) {
scope.challenges.forEach(function(challenge) {
//do something
}
}
scope.$watch('currentIndex', currentIndexChangeHandler);
will provoke that " currentIndexChangeHandler " will be triggered on the very first run (see: $watch is triggered directly after init, why? ), when " scope.challenges " is still undefined. 将引发“ currentIndexChangeHandler ”将在第一次运行时被触发(请参阅: $ watch在init之后直接触发,为什么? ),而“ scope.challenges ”仍未定义。
You colud "hack" this "first run" with " if(newValue!=oldValue) ", but I think this is not the point. 您用“ if(newValue!= oldValue) ”来“破解”该“首次运行”,但是我认为这不是重点。 Other problem is that when you iterate " scope.challenges ", it is undefined, because its value should be async received.
另一个问题是,当您迭代“ scope.challenges ”时,它是未定义的,因为它的值应该是异步接收的。 It could be solved using " if(Boolean(scope.challenges)) ", but it's not the right way.
可以使用“ if(Boolean(scope.challenges)) ”解决,但这不是正确的方法。
I think the real problem is that you are working with async data. 我认为真正的问题是您正在使用异步数据。
¿What value returns Challenge.findAll()? ¿什么值返回Challenge.findAll()? ¿maybe a promise?
¿可能是一个承诺? In this way you should use:
这样,您应该使用:
Challenge.findAll().then(function(challenges){
$scope.challenges = challenges;
}
I refactored your code with my sugestion. 我通过我的建议重构了您的代码。 Is that behaviour, what you was pretending?
那是你的假装吗?
http://jsfiddle.net/rizome/uqtaoLne/ http://jsfiddle.net/rizome/uqtaoLne/
UPDATE: 更新:
Using Firebase and $firebase (see: https://www.firebase.com/docs/web/libraries/angular/api.html#angularfire-firebase ) 使用Firebase和$ firebase(请参阅: https : //www.firebase.com/docs/web/libraries/angular/api.html#angularfire-firebase )
" $firebase " AngularJS wraper has a similar behaviour than coded in the fiddle above, but you should use " $firebase " api to obtain a promises. “ $ firebase” AngularJS包装器的行为与上面的小提琴中编码的行为类似,但是您应使用“ $ firebase ” api获得承诺。 (this piece of code represents code inside your repo-service, and inside the controller as well)
(这段代码代表您的回购服务内部以及控制器内部的代码)
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
});
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.