【问题标题】:AngularFire 3-way data binding is not updating firebase when a checkbox change复选框更改时,AngularFire 3路数据绑定不会更新firebase
【发布时间】:2014-02-17 19:58:21
【问题描述】:

我正在使用 AngularFire 模块使用 Angular 和 Firebase 开发一个简单的待办事项应用程序。

所以我的模型中有一个布尔属性,由模板中的复选框表示,问题是我正在尝试使用来自 AngularFire 的三向数据绑定,使用 $bind 方法来保持所有更改同步( firebase 数据、DOM 和 ng-model),但是当我选中一个复选框时,firebase 数据没有更新。

这是我使用 AngularFire $bind 方法的控制器:

angular.module('singularPracticeApp')
  .controller('TodoCtrl', ['$scope', 'TodoService', function ($scope, todoService) {
    $scope.todos = todoService;

    $scope.todos.$bind($scope, 'todo.done');

    $scope.addTodo = function () {
      $scope.todos.$add({text: $scope.todoText, done:false});
      $scope.todoText = '';
    };

    $scope.remaining = function () {
      var count = -11;
      angular.forEach($scope.todos, function(todo){
        count += todo.done? 0 : 1;
      });
      return count;
    };

    $scope.clear = function (id) {
      $scope.todos.$remove(id);
    };
  }]);

这是模板文件:

<div ng-controller="TodoCtrl">
  <h4>Task runner</h4>
  <span>{{remaining()}} todos left.</span>
  <ul>
    <li ng-repeat="(id, todo) in todos">
      <input type="checkbox" ng-model="todo.done">
      <span ng-if="todo.done" style="color: #ddd;">{{todo.text}}</span>
      <span ng-if="todo.done == false">{{todo.text}}</span>
      <small ng-if="todo.done"><a href="" ng-click="clear(id)">clear</a></small>
    </li>
  </ul>
  <form ng-submit="addTodo()">
    <input type="text" ng-model="todoText" placeholder="New todo item">
    <input type="submit" class="btn btn-primary" value="add">
  </form>
</div>  

我错过了什么吗?真的可以用一个简单的复选框来完成这项工作吗?

提前致谢。

【问题讨论】:

  • 您尚未指定待办事项对象,但您已绑定到其属性之一 (todo.done)。如果您只是绑定 $scope.done 或更直接的路径会发生什么?
  • @Kato 没有任何反应。我刚刚用完整的模板代码更新了这个问题。我希望它有所帮助。
  • 加藤,你能帮帮我吗? stackoverflow.com/questions/37847600/…

标签: javascript angularjs data-binding firebase angularfire


【解决方案1】:

您没有在此处包含 todoService,因此很难为您提供准确的答案。我假设 todoService 返回一个包含 todos 的 $firebase 实例,因为这似乎很可能。请记住,问题也可能出在该代码中。

您可以解决的几个问题可能会解决您的问题:

您的 TodoCtrl 不是每个项目

您似乎在使用 TodoCtrl,就好像它是在 ng-repeat 中按项目创建的一样。但是,它存在于 ng-repeat 范围之外,并且只为整个列表创建一次。

Ng-repeat 不会重复使用您现有的控制器范围。

Directives operate in an isolate scope。这意味着它们不与您的控制器共享范围。因此,当您执行 ng-repeat="todo in todos" 时,您不会将 todo 添加到控制器的范围内。

这是有道理的,因为每次 ng-repeat 迭代都会覆盖相同的 todo 对象。

您正在尝试双重绑定到同步对象

您正在尝试创建三向绑定$scope.todos.[$todo].done,但您已经在$scope.todos 上创建了三向绑定。相反,让 $scope.todos 负责同步。

您尝试将 $scope.todos 绑定到本身的属性

当您调用 $bind 时,您将 $scope.todos 绑定到 $scope.todos.todo.done。显然,这个自我引用的陈述不是你想要的。我不知道你的服务返回了什么,但也许你的意思是这样的:

todoService.$bind($scope, 'todos');

如果您不想在整个待办事项列表上自动推送更改,您可以添加 $save 调用而不是使用 $bind:

$scope.todos = todoService;

<input type="checkbox" ng-model="todo.done" ng-change="$parent.todos.$save(id)">

齐心协力:

angular.module('singularPracticeApp')
   .service('todoService', function($firebase) {
      return $firebase( new Firebase(URL_TO_TODOS_LIST) );
   });
   .controller('TodoCtrl', function($scope, todoService) {
      todoService.$bind($scope, 'todos');

      $scope.addTodo = function () {
         $scope.todos.$add({text: $scope.todoText, done:false});
         $scope.todoText = '';
      };

      /** ... and so on ... **/      
   });

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-01-31
    • 2010-10-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多