0

我正在尝试将 Firebase 和 AngularFire 用于我正在构建的应用程序。诚然,我是 Angular 和 Firebase 的新手,因此我们将不胜感激。

我在 Firebase 中有以下数据库结构:

  • 史诗
    • 史诗 1
      • ID
      • 标题等
    • 史诗 2
      • ID
      • 标题等
  • 用户

    • 用户 1

      -activeepics

      • 活跃史诗 1

      • 活跃史诗2

在下一页上,我对数据库中的每个史诗都有一个 ng-repeat。每个史诗都有一排按钮,其中一个给我带来了麻烦。如果当前用户已经开始了史诗(例如史诗出现在该用户的“活动史诗”中),那么按钮应该说“Tap Out”。如果史诗不在用户的活动史诗中,则应显示“开始”。

按钮在单击时应该执行不同的操作,具体取决于按钮标签。因此,如果按钮标签显示“开始”,应用程序应将史诗添加到当前用户的“活动史诗”中,并将按钮标签更改为“Tap Out”。相反,如果按钮标签是“Tap Out”,应用程序应该从“activeepics”中删除史诗,并将按钮标签改回“开始”。

但是,我得到了各种奇怪的行为。当我使用 1 或 0 等虚拟 ID 时,该应用程序会显示正确的按钮标签。但是,当我添加具有 Firebase 生成 ID 的史诗时,所有标签都会重置为“开始”。我还注意到,该应用程序多次循环遍历每个史诗(我为每个显示的史诗输入了调试 console.log)。

我认为问题可能是在将 Firebase 数据绑定到 $scope 后我有多个承诺对象。如果可以的话请帮忙!

这是代码:

看法

<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);
                    }
                }
            });
        });
4

2 回答 2

0

我认为您的部分问题可能是您试图遍历一个对象,就好像它是一个数组一样。如果您在 Firebase 中存储具有连续数字 id(0、1 等)的数据,AngularFire 会将您的数据视为数组。如果您使用键(例如使用 Firebase.push() 创建的键),AngularFire 会将您的数据视为键和值的字典。

我会指定您希望您的 angularFire 变量提前的数据类型,因此在调用之前插入$scope.users = []and$scope.activeEpics = {}或任何情况AngularFire(),然后检查对象以查看它们实际上是字典还是数组,并更改您的迭代方法得当。

于 2013-10-16T17:51:09.380 回答
0

首先回答您的直接问题:

  1. 为什么"Start"在添加 时所有标签都重置为epic

    您的$scope.getLabel方法正在尝试迭代$scope.activeEpics,这是一个angularFire承诺的结果。But$scope.activeEpics是一个对象,而不是数组,因此它没有索引或.length属性。即使这样做了,假设的结果数组元素也不会id像您期望的那样具有属性。相反,您正在寻找refname()与refactiveEpic进行比较name()epic这实际上简化了您的生活,因为您只想知道给定epic名称是否存在于您的activeEpics对象中,因此该方法可能如下所示:

    $scope.getLabel = function(epicName){
      var labelText = $scope.activeEpics[epicName] ? "Tap Out" : "Start";
      return labelText;
    }
    

    就目前而言,您的迭代没有运行,一切都恢复到"Start".

  2. 为什么你的$scope.getLabel函数执行了这么多次?

    这是 AngularJS 监视系统的一个功能,因为您的视图正在调用一个方法,然后该方法会更改视图,因此手表会再次运行,从而再次触发该方法(稍微粗略地说),依此类推需要标签的史诗。请参阅此 SO 答案以获得更好的解释。

如果我可以提供一些一般性建议,看起来您正试图通过他们的电子邮件以某种迂回的方式找到用户。您可以尝试使用 Firebase 优先级系统来更优雅地完成同样的事情,如此所述。如果您收紧格式并全面使用更明确的变量和参数命名,那么遵循代码也会更容易。只是我的两分钱。祝你好运!

于 2013-10-16T18:33:50.950 回答