我正在尝试将Firebase和AngularFire用于我正在构建的应用。我无疑是角度和Firebase的新手,所以任何帮助都会受到赞赏。
我在Firebase中有以下数据库结构:
USERS
用户1
-activeepics
活跃的史诗1
活跃的史诗2
在下一页上,我对数据库中的每个史诗都有一个ng-repeat。每个史诗都有一排按钮,其中一个给我带来麻烦。如果当前用户已经开始史诗(例如,史诗出现在该用户的“activeepics”中),则按钮应该说“点击”。如果史诗不在用户的主动视觉中,则应显示“开始”。
单击按钮时,按钮应执行不同的操作,具体取决于按钮标签。因此,如果按钮标签显示“开始”,则应用应将史诗添加到当前用户“activeepics”中,并将按钮标签更改为“Tap Out”。相反,如果按钮标签为“Tap Out”,应用程序应从“activeepics”中删除史诗,并将按钮标签更改回“Start”。
然而,我得到各种奇怪的行为。当我使用虚拟身份证(例如1或0)时,应用程序会显示正确的按钮标签。但是,当我添加带有Firebase生成ID的史诗时,所有标签都会重置为“开始”。我也注意到应用程序循环遍历每个史诗多次(我为每个史诗显示进入调试console.log)。
我认为问题可能是我将Firebase数据绑定到$ scope后有多个promise对象。如果可以的话请帮忙!
以下是代码:
查看
<div ng-repeat="(name,epic) in epics | filter:search | orderBy:order | filter:{category:category}" class="epic">
<div>
<div class="small-block-grid-3 epicActions">
<li><a href="#"> Remix </a></li>
<li><a href="#/share"> Share </a></li>
<li><a href="#" ng-click="handleLabel(name)" prevent> {{getLabel(name)}} </a></li>
</div>
</ul>
</div>
</div>
控制器
$scope.desiredUser = UserService.getCurrentUser();
var ref = new Firebase("https://epicly.firebaseio.com/epics");
angularFire(ref, $scope, 'epics');
var ref2 = new Firebase("https://epicly.firebaseio.com/users");
angularFire(ref2, $scope, 'users').then(function(){
for (var i = 0; i<$scope.users.length; i++){
if($scope.users[i].email === $scope.desiredUser){
$scope.currUser = $scope.users[i];
}
}
var ref3 = new Firebase("https://epicly.firebaseio.com/users/" + $scope.currUser.id + "/activeepics");
angularFire(ref3, $scope, 'activeEpics').then(function(){
console.log($scope.activeEpics);
$scope.getLabel = function(epic){
console.log(epic);
for(var i = 0; i < $scope.activeEpics.length; i++){
if ($scope.activeEpics[i].id === epic) {
return "Tap Out";
}
}
return "Start";
}
$scope.handleLabel = function(name){
var label = $scope.getLabel(name);
if(label === "Tap Out"){
//remove from active epics
} else {
//add to activeepics
$scope.toAdd = {"id": name}
$scope.activeEpics.push($scope.toAdd);
}
}
});
});
答案 0 :(得分:0)
我认为您的部分问题可能是您尝试迭代对象,就像它是一个数组一样。如果您使用连续数字ID(0,1等)在Firebase中存储数据,AngularFire会将您的数据视为数组。如果您使用密钥(例如使用Firebase.push()创建的密钥),AngularFire会将您的数据视为密钥和值的字典。
我会指定您期望angularFire变量提前的数据类型,因此在调用$scope.users = []
之前插入$scope.activeEpics = {}
和AngularFire()
,或者不管是什么情况,然后检查对象以查看它们是否实际上是字典或数组,并适当地更改迭代方法。
答案 1 :(得分:0)
首先回答您的直接问题:
为什么添加"Start"
时所有标签都会重置为epic
?
您的$scope.getLabel
方法正在尝试迭代$scope.activeEpics
angularFire
承诺的结果。但是$scope.activeEpics
是一个对象,而不是一个数组,因此它没有索引或.length
属性。即使它确实如此,假设的结果数组元素也不会像您期望的那样具有id
属性。相反,您正在寻找name()
引用的activeEpic
与name()
引用的epic
进行比较。这实际上简化了您的生活,因为您只想知道epic
对象中是否存在给定的activeEpics
名称,因此该方法可能如下所示:
$scope.getLabel = function(epicName){
var labelText = $scope.activeEpics[epicName] ? "Tap Out" : "Start";
return labelText;
}
目前,您的迭代未运行,所有内容都恢复为"Start"
。
为什么你的$scope.getLabel
函数执行了这么多次?
这是AngularJS观察系统的一个功能,因为你的视图正在调用一个方法然后改变视图,所以手表再次运行,再次触发该方法(稍微粗略地说),依此类推等等对于所有需要标签的史诗。有关更好的解释,请参阅this SO answer。
如果我可以提供一些一般性建议,看起来您正试图通过他们的电子邮件以某种迂回的方式找到用户。您可以尝试使用Firebase优先级系统来更优雅地完成相同的操作,如here所述。如果您加强格式化并使用更明确的变量和参数命名,那么遵循代码也会更容易。只是我的两分钱。祝你好运!