angularFire 3路数据绑定无法更新功能

时间:2015-05-15 02:22:24

标签: javascript angularjs data-binding firebase

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

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);
    });
根据@Kato解决方案

更新1 : 我决定使用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);
   });

我更新了用户对象,除非我刷新页面,否则lessonCount值没有改变。并且$ watch里面的console.log根本没有运行。怎么了?

1 个答案:

答案 0 :(得分:1)

$ bindTo返回的promise只调用一次。它不是一个事件监听器。每次发生变化时,您都无法收听此信息。

请先阅读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()代替范围方法,这样可以提高效率。

编写了很大一部分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);
   });
});