单击复选框并调用ng-click:在ng-click开始之前模型不会更新,因此UI中错误地显示了复选框值:
这适用于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/
答案 0 :(得分:159)
如何改变
<input type='checkbox' ng-click='onCompleteTodo(todo)' ng-model="todo.done">
到
<input type='checkbox' ng-change='onCompleteTodo(todo)' ng-model="todo.done">
来自docs:
用户更改输入时评估给定的表达式。当值更改来自模型时,不会计算表达式。
请注意,此指令要求
ngModel
存在。
答案 1 :(得分:11)
如https://github.com/angular/angular.js/issues/4765所述,从ng-click切换到ng-change似乎解决了这个问题(我使用的是Angular 1.2.14)
答案 2 :(得分:9)
执行ng-click
和ng-model
的顺序不明确(因为两者都未明确设置其priority
)。对此最稳定的解决方案是避免在同一元素上使用它们。
此外,您可能不希望示例显示的行为;您希望checkbox
响应完整标签文字的点击次数,而不仅仅是复选框。因此,最干净的解决方案是将input
(ng-model
)包裹在label
(ng-click
)中:
<label ng-click="onCompleteTodo(todo)">
<input type='checkbox' ng-model="todo.done">
{{todo.text}}
</label>
答案 3 :(得分:8)
为什么不使用
$watch('todo',function(.....
或者另一种解决方案是在ng-click回调中设置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;
}
答案 4 :(得分:6)
用ng-checked更换ng-model对我有效。
答案 5 :(得分:2)
这是一种黑客行为,但将其包裹在超时中似乎可以实现您的目标:
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;
});
};
}]);
答案 6 :(得分:1)
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/
答案 7 :(得分:0)
通常这是由于你的ng-controller之间的另一个指令 和您正在创建新范围的输入。当select写入时 超出它的价值,它会把它写到最近的范围,所以它 将它写入此范围而不是更进一步的父级 远。
最佳做法是永远不要直接绑定到作用域上的变量 在
ng-model
中,这也被称为始终包括&#34;点&#34;在 你的ngmodel。有关此问题的更好解释,请查看此视频 来自约翰:
解决方案来自:https://groups.google.com/forum/#!topic/angular/7Nd_me5YrHU
答案 8 :(得分:0)
我刚刚将ng-model
替换为ng-checked
,这对我有用。
此问题是我将角度版本从1.2.28
更新为1.4.9
另请检查ng-change
是否在此处引起任何问题。我不得不删除我的ng-change
以使其正常工作。
答案 9 :(得分:-1)
.task{ng:{repeat:'task in model.tasks'}}
%input{type:'checkbox',ng:{model:'$parent.model.tasks[$index].enabled'}}