添加到数组的AngularFire清除$ scope变量

时间:2014-12-19 07:12:26

标签: angularjs firebase angularfire

当我向嵌套的AngularFire $ asArray()对象添加内容时,我遇到了一个奇怪的问题。不知道怎么解释它而不粘贴我的所有代码所以请耐心等待。

我的模板是这样的:

<ion-content ng-controller='WorkoutCtrl as workoutCtrl' data-ng-init="init()">
  <div ng-hide="workoutCtrl.isExercising" class="card">
    <label class="item item-input">
      <input ng-enter="createExercise(newExercise)" ng-model="newExercise" type="text" placeholder="Type exercise here...">
    </label>
  </div>
  <div ng-click="startExercise()" class="card" ng-controller="ExerciseCtrl" ng-repeat="exercise in exercises" data-ng-init="init()">
    <div class="item item-divider">
      {{ exercise.name }}
    </div>
    <div class="item item-text-wrap">
      <button class="button" ng-click="createSet()" ng-show="exercise.isActive">
        Tap to add set
      </button>
    </div>
    <div class="item item-divider" ng-show="exercise.isActive">
      <button class="button icon ion-minus-circled" ng-click="addReps(-1)"></button>
      {{ exercise.numReps + ' reps' }}
      <button class="button icon ion-plus-circled" ng-click="addReps(1)"></button>
      <div class="range">
        <input type="range" name="volume" min="1" max="10" ng-model="exercise.numReps">
      </div>
    </div>
  </div>
  <div class="card bottom-btn-wrapper">
    <button ng-hide="workoutCtrl.isExercising" class="button button-block button-positive done-workout">
      I'm done working out!
    </button>
    <button ng-show="workoutCtrl.isExercising" ng-click="finishExercises()" class="button button-block button-positive done-exercise">
      Finish Exercise
    </button>
  </div>
</ion-content>

这是我的控制器:

controllers.controller('WorkoutCtrl', [
  '$scope',
  'FirebaseUrl',
  '$firebase',
  function ($scope, FirebaseUrl, $firebase) {
    var self = this;
    var fireRef;

    $scope.init = function () {
      self.isExercising = false;
      self.workoutId = 1;
      fireRef = new Firebase(FirebaseUrl + '/workouts/' + self.workoutId);

      $firebase(fireRef).$update({ date: new Date() });
      $scope.exercises = $firebase(fireRef.child('exercises')).$asArray();
    };

    $scope.createExercise = function (name) {
      $scope.newExercise = '';
      $scope.exercises.$add({ name: name });
    };

    $scope.finishExercises = function () {
      angular.forEach($scope.exercises, function (exercise) {
        exercise.isActive = false;
      });
      self.isExercising = false;
    };
  }
]);

controllers.controller('ExerciseCtrl', [
  '$scope',
  'FirebaseUrl',
  '$firebase',
  function ($scope, FirebaseUrl, $firebase) {
    var fireRef;

    $scope.init = function () {
      fireRef = new Firebase(FirebaseUrl + '/workouts/' + $scope.workoutCtrl.workoutId + '/exercises/' + $scope.exercise.$id + '/sets');

      $scope.exercise.isActive = false;
      $scope.exercise.numReps = '8';
      $scope.exercise.sets = $firebase(fireRef).$asArray();
    };

    $scope.startExercise = function () {
      $scope.finishExercises();
      $scope.exercise.isActive = true;
      $scope.workoutCtrl.isExercising = true;
    };

    $scope.addReps = function (repsToAdd) {
      var reps = parseInt($scope.exercise.numReps) + repsToAdd;

      if (reps > 0 && reps < 100) {
        $scope.exercise.numReps = reps.toString();
      }
    };

    $scope.createSet = function () {
      $scope.exercise.sets.$add({reps: $scope.exercise.numReps});
    };
  }
]);

我遇到的问题是当我单击调用createSet()方法的按钮时。这在我的Firebase数据库中成功创建了一个新对象,但在这样做之后,由于某种原因$scope.exercise.isActive$scope.numReps不再具有价值。有什么想法在这里发生了什么?

1 个答案:

答案 0 :(得分:2)

我怀疑问题是来自服务器的更新没有isActivenumReps显示属性。

  1. WorkoutCtrl获取一组初始练习对象,作为观察整个练习数据树的Firebase数组。
  2. 为一个练习对象初始化ExerciseCtrl,在练习记录中添加不在Firebase中的本地属性(isActivenumReps)。
  3. ExerciseCtrl.createSet()通过exercise.sets。$ add()更新练习记录。您似乎依靠服务器仅为集合列表提供更新。
  4. 但是,服务器还会对WorkoutCtrl.excercises数组进行更新,因为其中一个练习已更改。
  5. 执行更新会清除您在ExerciseCtrl范围内本地添加的属性。
  6. 您可以在excercises数组上使用$watch并观察更新何时返回来验证这一点。

    我通过extending the Firebase Array Factory解决了类似的问题,将我的自定义包装器对象返回到原始数据记录上。解决这个问题需要做一些工作,但它提供了很多自由来添加未存储在Firebase中的UI行为建模。 WidgetFactory示例非常接近您的需要。