用ng-click单击checkbox不会更新模型

点击一个checkbox并调用ng-click:模型在ng-click开始前没有更新,所以在UI中错误地显示了checkbox的值:

这在AngularJS 1.0.7中工作,似乎在Angualar 1.2-RCx中被破坏。

<div ng-app="myApp" ng-controller="Ctrl"> <li ng-repeat="todo in todos"> <input type='checkbox' ng-click='onCompleteTodo(todo)' ng-model="todo.done"> {{todo.text}} </li> <hr> task: {{todoText}} <hr><h2>Wrong value</h2> done: {{doneAfterClick}} 

和控制器:

 angular.module('myApp', []) .controller('Ctrl', ['$scope', function($scope) { $scope.todos=[ {'text': "get milk", 'done': true }, {'text': "get milk2", 'done': false } ]; $scope.onCompleteTodo = function(todo) { console.log("onCompleteTodo -done: " + todo.done + " : " + todo.text); $scope.doneAfterClick=todo.done; $scope.todoText = todo.text; }; }]); 

破碎的小提琴w / Angular 1.2 RCx – http://jsfiddle.net/supercobra/ekD3r/

使用Angular 1.0.0工作的小提琴 – http://jsfiddle.net/supercobra/8FQNw/

如何改变

 <input type='checkbox' ng-click='onCompleteTodo(todo)' ng-model="todo.done"> 

 <input type='checkbox' ng-change='onCompleteTodo(todo)' ng-model="todo.done"> 

从文档 :

在用户更改input时评估给定的expression式。 当值改变来自模型时,expression式不被评估。

请注意,这个指令要求ngModel存在。

ng-clickng-model将被执行的顺序是不明确的(因为没有明确地设置它们的priority )。 最稳定的解决scheme是避免在同一个元素上使用它们。

另外,你可能不希望这个例子显示的行为; 你希望checkbox响应点击完整的标签文本 ,而不仅仅是checkbox。 因此,最简洁的解决scheme是将input (使用ng-model )包装在label (使用ng-click ):

 <label ng-click="onCompleteTodo(todo)"> <input type='checkbox' ng-model="todo.done"> {{todo.text}} </label> 

工作示例: http : //jsfiddle.net/b3NLH/1/

你为什么不使用

 $watch('todo',function(..... 

或者另一个解决scheme是在ng-clickcallback中设置todo.done ,并且只使用ng-click

 <div ng-app="myApp" ng-controller="Ctrl"> <li ng-repeat="todo in todos"> <input type='checkbox' ng-click='onCompleteTodo(todo)'> {{todo.text}} {{todo.done}} 

 $scope.onCompleteTodo = function(todo) { todo.done = !todo.done; //toggle value console.log("onCompleteTodo -done: " + todo.done + " : " + todo.text); $scope.current = todo; } 

用ng-checkedreplaceng-model适合我。

这是一种黑客,但在超时包装它似乎完成你在找什么:

 angular.module('myApp', []) .controller('Ctrl', ['$scope', '$timeout', function ($scope, $timeout) { $scope.todos = [{ 'text': "get milk", 'done': true }, { 'text': "get milk2", 'done': false }]; $scope.onCompleteTodo = function (todo) { $timeout(function(){ console.log("onCompleteTodo -done: " + todo.done + " : " + todo.text); $scope.doneAfterClick = todo.done; $scope.todoText = todo.text; }); }; }]); 

ng-modelng-click之间的顺序似乎是不同的,这是你可能不应该依赖的。 相反,你可以做这样的事情:

 <div ng-app="myApp" ng-controller="Ctrl"> <li ng-repeat="todo in todos"> <input type='checkbox' ng-model="todo.done" ng-click='onCompleteTodo(todo)'> {{todo.text}} {{todo.done}} </li> <hr> task: {{current.text}} <hr> <h2>Wrong value</h2> done: {{current.done}} </div> 

和你的脚本:

 angular.module('myApp', []) .controller('Ctrl', ['$scope', function($scope) { $scope.todos=[ {'text': "get milk", 'done': true }, {'text': "get milk2", 'done': false } ]; $scope.current = $scope.todos[0]; $scope.onCompleteTodo = function(todo) { console.log("onCompleteTodo -done: " + todo.done + " : " + todo.text); //$scope.doneAfterClick=todo.done; //$scope.todoText = todo.text; $scope.current = todo; }; }]); 

这里的不同之处在于,无论何时单击一个框,它都会将该框设置为“当前”,然后在视图中显示这些值。 http://jsfiddle.net/QeR7y/

通常这是由于你的ng-controller和你正在创build一个新的范围的input之间的另一个指令。 当select写出它的值时,它会把它写到最近的作用域,所以它会把它写到这个作用域,而不是远离它的父对象。

最好的做法是不要直接绑定到ng-model中的variables上,这也被称为在你的ngmodel中总是包含一个“点”。 为了更好地解释这一点,请查看John的video:

http://www.youtube.com/watch?v=DTx23w4z6Kc

解决scheme来自: https : //groups.google.com/forum/#!topic/angular/7Nd_me5YrHU

我刚刚用ng-checkedreplace了ng-model ,它对我有效。

这个问题是当我更新我的angular度版本从1.2.281.4.9

同时检查你的ng-change是否在这里引起任何问题。 我不得不删除我的ng-change ,以使其工作。

 .task{ng:{repeat:'task in model.tasks'}} %input{type:'checkbox',ng:{model:'$parent.model.tasks[$index].enabled'}}