Щелчок по флажку с 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/
Ответы
Ответ 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
.
Ответ 2
Как сообщается в https://github.com/angular/angular.js/issues/4765, переключение с ng-click на ng-change похоже на исправление (я использую Angular 1.2.14)
Ответ 3
Порядок, в котором будут выполняться 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>
Рабочий пример: 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'}}