web-dev-qa-db-ja.com

ng-clickでチェックボックスをクリックしてもモデルは更新されません

チェックボックスをクリックして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/

83
supercobra

交換はいかがですか

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

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

docs から:

ユーザーが入力を変更したときに、指定された式を評価します。値の変更がモデルから発生している場合、式は評価されません。

このディレクティブにはngModelが必要であることに注意してください。

159
kakoni

https://github.com/angular/angular.js/issues/4765 で報告されているように、ng-clickからng-changeに切り替えると、これが修正されるようです(私はAngular 1.2.14)

11

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/

9
musically_ut

なぜ使用しないでください

$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;
}
8
GuillaumeA

Ng-modelをng-checkedに置き換えるとうまくいきます。

6
zzjove

それは一種のハックですが、タイムアウトでラップすることはあなたが探しているものを達成するようです:

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

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/

1
Manny D

ng-modelng-checkedに置き換えただけで、うまくいきました。

この問題は、angularバージョンを1.2.28から1.4.9に更新したときに発生しました

ここでng-changeが問題を引き起こしていないかどうかも確認してください。 ng-changeを削除する必要がありました。

0
thatzprem

通常、これは、ng-controllerと新しいスコープを作成している入力の間にある別のディレクティブによるものです。 selectはその値を書き出すときに、最新のスコープまで書き込みます。そのため、より遠くにある親ではなく、このスコープに書き込みます。

ベストプラクティスは、ng-modelのスコープ上の変数に直接バインドしないことです。これは、ngmodelに常に「ドット」を含めることとしても知られています。これについてのより良い説明については、ジョンの次のビデオをご覧ください。

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

ソリューション: https://groups.google.com/forum/#!topic/angular/7Nd_me5YrH

0
fergusrg