【问题标题】:angularFire 3 way data binding won't update an functionangularFire 3 方式数据绑定不会更新函数
【发布时间】:2015-05-15 02:22:23
【问题描述】:

我有一个 firebaseObject (MyFirebaseService.getCurrentUser()) 绑定到 $scope.user。 绑定成功后,我循环该对象以查看该对象是否包含等于某个值($stateParams.id)的“associatedCourseId”。如果是,则 $scope.finishLessonCount 计数。问题是,当我通过其他页面或 firebase 内部的 firebaseObject(即绑定用户)添加新对象时,finishLessonCount 值不会像我期望的 3 路绑定那样改变。我需要刷新页面以查看 finishLessonCount 反映真实值。怎么了?当我将更多的finishedLessons 添加到firebaseObject 中时,我希望使用比较函数来改变finishLessonCount。请看下面的代码:

MyFirebaseService.getCurrentUser().$bindTo($scope, "user").then(function(){

        for (var key in $scope.user.finishedLessons) {
            if ($scope.user.finishedLessons.hasOwnProperty(key)) {

                if ($scope.user.finishedLessons[key].associatedCourseId == $stateParams.id) {
                    $scope.finishLessonCount++;
                }
            }
        };
        console.log ($scope.finishLessonCount);
    });

UPDATE 1 根据@Kato 解决方案: 我决定使用 Extending firebaseOject 的方式来解决这个问题。但是,它仍然没有。我没有在这里使用工厂来简化事情,因为我需要传入 courseId 来进行操作。这是我的代码:

       function countLessons(lessons, courseId) {
       var count = 0;
       for(var key in lessons) {
          if( lessons[key].associatedCourseId ==  courseId) {
             count++;
          }
       }
       return count;
    }

    var UserWithLessonsCounter = $firebaseObject.$extend({
      $$updated: function(snap) {
         var changed = $firebaseObject.prototype.$$updated.call(this, snap);
         this.lessonCount = countLessons(this.finishedLessons, $stateParams.id);
      }
    });

    var refTemp = new Firebase($rootScope.baseUrl + "users/" + $rootScope.userId);
    var userTemp = new UserWithLessonsCounter(refTemp);

    userTemp.$bindTo($scope, "userTemp").then(function(){
        console.log($scope.userTemp);
    });
    userTemp.$watch(function() {
      console.log("Does this run at all? " + $scope.userTemp.lessonCount);
   });

我更新了用户对象,课程计数值没有改变,除非我刷新页面。 $watch 中的 console.log 根本没有运行。怎么了?

【问题讨论】:

  • 很可能,您应该将课程存储在in their own path,而不是在用户节点中囤积数据。这也意味着您应该使用 $firebaseArray 而不是 $firebaseObject 来显示该数据。

标签: javascript angularjs data-binding firebase


【解决方案1】:

$bindTo 返回的承诺只被调用一次。它不是事件监听器。每次有变化时,你都不能听这个来更新。

请阅读the guide,从头到尾阅读Angular的$watch方法,然后再继续这条路线,因为有了一些基础知识,这不应该是你的第一直觉。

初学者的方法是使用 $watch:

MyFirebaseService.getCurrentUser().$bindTo($scope, "user");

$scope.$watch('user', function() {
   for (var key in $scope.user.finishedLessons) {
      if ($scope.user.finishedLessons.hasOwnProperty(key)) {
        if ($scope.user.finishedLessons[key].associatedCourseId == $stateParams.id) {
          $scope.finishLessonCount++;
        }
      }
   };
   console.log ($scope.finishLessonCount);
});

或者,在熟悉 AngularFire API 之后,可能会选择 $scope.user.$watch() 来代替 scope 方法,这样会更有效。

在编写了大部分 AngularFire 代码之后,我会选择 $extend 工具,该工具是专门为这样的用例添加的:

// making some assumptions here since you haven't included
// the code for your firebase service, which does not seem SOLID
app.factory('UserWithLessonsCounter', function($firebaseObject) {
   return $firebaseObject.$extend({
      $$updated: function(snap) {
         var changed = $firebaseObject.prototype.$$updated.call(this, snap);
         this.lessonCount = countLessons(this.finishedLessons);
         return changed;
      }
   });
});

function countLessons(lessons) {
   var count = 0;
   for(var key in lessons) {
      if( lessons.hasOwnProperty(key) ) {
         count++;
      }
   }
   return count;
}

现在在你的控制器中:

app.controller('...', function($scope, UserWithLessonsCounter) {
   var ref = new Firebase(...);
   var user = new UserWithLessonCounter(ref);
   user.$bindTo($scope, 'user');

   user.$watch(function() {
      console.log($scope.user.lessonCount);
   });
});

【讨论】:

  • 感谢@Kato 的澄清。我正在研究您使用 $watch 的初学者方法。这种方法的问题是,$scope.user.finishedLessons 将是未定义的。因为 $scope.$watch 在 $scope.user 之前运行,得到 Firebase 返回的数据。我实际上已经尝试 $watch 了,这就是阻止我的问题。我从不使用 $extend。如果可行,我将更仔细地研究此方法并报告。再次感谢您!
猜你喜欢
  • 2014-02-17
  • 1970-01-01
  • 2015-10-01
  • 1970-01-01
  • 1970-01-01
  • 2011-02-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多