チェックボックスをクリックして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;
};
}]);
壊れたFiddle w/Angular 1.2 RCx- http://jsfiddle.net/supercobra/ekD3r/
ワーキングフィドルw/Angular 1.0.0- http://jsfiddle.net/supercobra/8FQNw/
交換はいかがですか
<input type='checkbox' ng-click='onCompleteTodo(todo)' ng-model="todo.done">
に
<input type='checkbox' ng-change='onCompleteTodo(todo)' ng-model="todo.done">
docs から:
ユーザーが入力を変更したときに、指定された式を評価します。値の変更がモデルから発生している場合、式は評価されません。
このディレクティブには
ngModel
が必要であることに注意してください。
https://github.com/angular/angular.js/issues/4765 で報告されているように、ng-clickからng-changeに切り替えると、これが修正されるようです(私はAngular 1.2.14)
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>
なぜ使用しないでください
$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;
}
Ng-modelをng-checkedに置き換えるとうまくいきます。
それは一種のハックですが、タイムアウトでラップすることはあなたが探しているものを達成するようです:
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;
});
};
}]);
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/
ng-model
をng-checked
に置き換えただけで、うまくいきました。
この問題は、angularバージョンを1.2.28
から1.4.9
に更新したときに発生しました
ここでng-change
が問題を引き起こしていないかどうかも確認してください。 ng-change
を削除する必要がありました。
通常、これは、ng-controllerと新しいスコープを作成している入力の間にある別のディレクティブによるものです。 selectはその値を書き出すときに、最新のスコープまで書き込みます。そのため、より遠くにある親ではなく、このスコープに書き込みます。
ベストプラクティスは、
ng-model
のスコープ上の変数に直接バインドしないことです。これは、ngmodelに常に「ドット」を含めることとしても知られています。これについてのより良い説明については、ジョンの次のビデオをご覧ください。
ソリューション: https://groups.google.com/forum/#!topic/angular/7Nd_me5YrH