用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
存在。
正如在https://github.com/angular/angular.js/issues/4765中所报道的,从ng-click切换到ng-change似乎解决了这个问题(我正在使用Angular 1.2.14)
ng-click
和ng-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-model
和ng-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:
解决scheme来自: https : //groups.google.com/forum/#!topic/angular/7Nd_me5YrHU
我刚刚用ng-checked
replace了ng-model
,它对我有效。
这个问题是当我更新我的angular度版本从1.2.28
到1.4.9
同时检查你的ng-change
是否在这里引起任何问题。 我不得不删除我的ng-change
,以使其工作。
.task{ng:{repeat:'task in model.tasks'}} %input{type:'checkbox',ng:{model:'$parent.model.tasks[$index].enabled'}}