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


85

チェックボックスをクリックしてng-clickを呼び出す:ng-clickが起動する前にモデルが更新されないため、チェックボックスの値がUIに誤って表示されます。

これはAngularJS1.0.7で機能し、Angualar1.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;

   };
}]);

Angular 1.2RCx付きの壊れたフィドル-http //jsfiddle.net/supercobra/ekD3r/

/アンギュラ1.0.0ワットの作業fidddle - http://jsfiddle.net/supercobra/8FQNw/


3
また、Angularを1.2+に更新したので壊れました
ac360 2013

v1.2.24でも壊れています。
Vincent P

回答:


165

変えてみませんか

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

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

ドキュメントから:

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

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


3
これもバージョン1.2.7で壊れているようです
JvdBerg 2014年

聖なる電球、バットマン!私は何か他のことを完全に間違っていると思っていましたが、それはこれと同じくらい簡単であることがわかりました。
アダムマーシャル

1
非常に役立つ答えです!+1 Angular doc -1
neurix 2014

Defaultを防ぐためにイベントデータが必要な場合はどうなりますか?
user1943442 2015


9

順番に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/


どうもありがとう!これは私に働いた唯一の解決策です!
DaniCE 2015

このソリューションはまだ最高です!
エリサン2017

8

なぜあなたは使わないのですか

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

2
@kakoniの回答を参照してください。ng-clickの代わりにng-changeを使用しましたが、タイミングはうまく機能しています。これにより、双方向のバインディングを維持でき、はるかにクリーンなアプローチになります。
Michael Moser 2014

6

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


まさに私が欲しかったもの。ありがとう!
アイザック

ここで利用可能なすべてのソリューションから私のために働いただけです。
thatzprem 2016年

2

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

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

1

間の順序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/


0

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

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

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

解決策:https//groups.google.com/forum/#!topic / angular / 7Nd_me5YrHU


#t=5m08sYouTubeリンクにジャンプマーカーを指定して、ビデオ全体を見る必要がないようにすると便利です。参照してくださいmattcutts.com/blog/link-to-youtube-minute-second
フォルカー・E.

0

私はちょうど交換ng-modelしました、ng-checkedそしてそれは私のために働きました。

この問題は、私は私からの角度のバージョンを更新したとき1.2.281.4.9

また、ng-changeここで問題が発生していないかどうかを確認してください。私はng-changeそれを機能させるために自分の井戸を取り除く必要がありました。


弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.