单击带有ng-click的复选框不会更新模型

时间:2013-10-21 14:09:09

标签: angularjs checkbox

单击复选框并调用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/

10 个答案:

答案 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-clickng-model的顺序不明确(因为两者都未明确设置其priority)。对此最稳定的解决方案是避免在同一元素上使用它们。

此外,您可能不希望示例显示的行为;您希望checkbox响应完整标签文字的点击次数,而不仅仅是复选框。因此,最干净的解决方案是将inputng-model)包裹在labelng-click)中:

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

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

答案 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-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/

答案 7 :(得分:0)

  

通常这是由于你的ng-controller之间的另一个指令   和您正在创建新范围的输入。当select写入时   超出它的价值,它会把它写到最近的范围,所以它   将它写入此范围而不是更进一步的父级   远。

     

最佳做法是永远不要直接绑定到作用域上的变量   在ng-model中,这也被称为始终包括&#34;点&#34;在   你的ngmodel。有关此问题的更好解释,请查看此视频   来自约翰:

     

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

解决方案来自: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'}}