Clicking a checkbox with ng-click does not update the model

前端 未结 10 1655
太阳男子
太阳男子 2020-12-04 13:17

Clicking on a checkbox and calling ng-click: the model is not updated before ng-click kicks in so the checkbox value is wrongly presented in the UI:

This works in An

相关标签:
10条回答
  • 2020-12-04 13:37

    How about changing

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

    to

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

    From docs:

    Evaluate given expression when user changes the input. The expression is not evaluated when the value change is coming from the model.

    Note, this directive requires ngModel to be present.

    0 讨论(0)
  • 2020-12-04 13:37

    Why dont you use

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

    Or another solution would be to set the todo.done inside the ng-click callback and only use 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}}
    

    and

    $scope.onCompleteTodo = function(todo) {
            todo.done = !todo.done; //toggle value
            console.log("onCompleteTodo -done: " + todo.done + " : " + todo.text);
            $scope.current = todo;
    }
    
    0 讨论(0)
  • 2020-12-04 13:40

    Usually this is due to another directive in-between your ng-controller and your input that is creating a new scope. When the select writes out it value, it will write it up to the most recent scope, so it would write it to this scope rather than the parent that is further away.

    The best practice is to never bind directly to a variable on the scope in an ng-model, this is also known as always including a "dot" in your ngmodel. For a better explanation of this, check out this video from John:

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

    Solution from: https://groups.google.com/forum/#!topic/angular/7Nd_me5YrHU

    0 讨论(0)
  • 2020-12-04 13:42

    The ordering between ng-model and ng-click seems to be different and it's something you probably shouldn't rely on. Instead you could do something like this:

    <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>
    

    And your script:

    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;
    
       };
    }]);
    

    What's different here is whenever you click a box, it sets that box as what's "current" and then display those values in the view. http://jsfiddle.net/QeR7y/

    0 讨论(0)
  • 2020-12-04 13:45

    As reported in https://github.com/angular/angular.js/issues/4765, switching from ng-click to ng-change seems to fix this (I am using Angular 1.2.14)

    0 讨论(0)
  • 2020-12-04 13:45

    It is kind of a hack but wrapping it in a timeout seems to accomplish what you are looking for:

    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;
            });
        };
    }]);
    
    0 讨论(0)
提交回复
热议问题