Подтвердить что ты не робот

Щелчок по флажку с ng-click не обновляет модель

Нажав на флажок и вызывая ng-click: модель не обновляется до того, как ng-click выйдет, поэтому значение флажка неверно представлено в пользовательском интерфейсе:

Это работает в 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/

Рабочее fidddle w/Angular 1.0.0  - http://jsfiddle.net/supercobra/8FQNw/

4b9b3361

Ответ 1

Как насчет изменения

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

к

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

От docs:

Оцените данное выражение, когда пользователь меняет ввод. Выражение не оценивается, когда изменение значения происходит из модели.

Примечание. Для этой директивы требуется ngModel.

Ответ 3

Порядок, в котором будут выполняться ng-click и ng-model, является неоднозначным (поскольку ни одно из них явно не задает их priority). Наиболее устойчивым решением для этого было бы избежать использования их на одном элементе.

Кроме того, вы, вероятно, не хотите, чтобы поведение показывало примеры; вы хотите, чтобы checkbox отвечал на клики на полный текст ярлыка, а не только на флажке. Следовательно, самым чистым решением было бы обернуть inputng-model) внутри label (с помощью ng-click):

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

Рабочий пример: http://jsfiddle.net/b3NLH/1/

Ответ 4

Почему вы не используете

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

Или другим решением было бы установить todo.done внутри обратного вызова ng-click и использовать только 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;
}

Ответ 5

Замена ng-модели на ng-checked работает для меня.

Ответ 6

Это своего рода хак, но его завершение в тайм-аут, похоже, выполняет то, что вы ищете:

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

Ответ 7

Порядок между 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>

И ваш 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;

   };
}]);

Чем отличается каждый раз, когда вы нажимаете поле, он устанавливает это поле как "текущее", а затем отображает эти значения в представлении. http://jsfiddle.net/QeR7y/

Ответ 8

Обычно это связано с другой директивой между вашим ng-контроллером и ваш ввод, создающий новую область. Когда запись выбора внесите его значение, оно будет записывать его до самой последней области, поэтому будет записывать его в эту область действия, а не родитель, далеко.

Лучшей практикой является никогда не привязывать напрямую к переменной в области в ng-model, это также известно, как всегда, включая "точку" в ваш ngмодель. Для лучшего объяснения этого, просмотрите это видео от Джона:

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

Решение от: https://groups.google.com/forum/#!topic/angular/7Nd_me5YrHU

Ответ 9

Я только что заменил ng-model на ng-checked, и это сработало для меня.

Эта проблема возникла, когда я обновил версию angular от 1.2.28 до 1.4.9

Также проверьте, не вызывает ли ваш ng-change все проблемы. Мне пришлось удалить мой ng-change как-то, чтобы он работал.

Ответ 10

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