84 votes

Cliquer sur une case avec ng-click ne met pas à jour le modèle

En cliquant sur une case à cocher et de l'appel de ng-click: le modèle n'est pas mis à jour avant ng-cliquez sur coups de pied dans la case de valeur est à tort présenté dans l'INTERFACE utilisateur:

Cela fonctionne dans AngularJS 1.0.7 et semble cassé dans 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}}

et du contrôleur:

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;

   };
}]);

Cassé Violon w/ Angulaire 1.2 RCx - http://jsfiddle.net/supercobra/ekD3r/

Travail fidddle w/ Angulaire 1.0.0 - http://jsfiddle.net/supercobra/8FQNw/

164voto

kakoni Points 1316

Que diriez-vous de changer

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

à

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

De docs :

Évaluez l'expression donnée lorsque l'utilisateur modifie l'entrée. L'expression n'est pas évaluée lorsque le changement de valeur provient du modèle.

Notez que cette directive requiert que ngModel soit présent.

11voto

Comme indiqué dans https://github.com/angular/angular.js/issues/4765 , passer de ng-click à ng-change semble résoudre ce problème (j'utilise Angular 1.2.14).

9voto

musically_ut Points 13260

L'ordre dans lequel ng-click et ng-model sera exécutée est ambigu (puisque ni de définir explicitement leur priority). Le plus stable de la solution à ce problème serait d'éviter de les utiliser sur le même élément.

Aussi, vous ne voulez probablement pas le comportement que le montrent les exemples; vous voulez l' checkbox à répondre aux clics sur le texte de l'étiquette, non seulement la case à cocher. Par conséquent, la solution la plus propre serait pour envelopper l' input (avec ng-model) à l'intérieur d'un label (avec ng-click):

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

Exemple: http://jsfiddle.net/b3NLH/1/

8voto

GuillaumeA Points 524

Pourquoi n'utilisez-vous pas

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

Ou une autre solution consisterait à définir le todo.done dans le rappel ng-click et à n’utiliser que 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}}
 

et

 $scope.onCompleteTodo = function(todo) {
        todo.done = !todo.done; //toggle value
        console.log("onCompleteTodo -done: " + todo.done + " : " + todo.text);
        $scope.current = todo;
}
 

2voto

moderndegree Points 3674

C'est un peu un bidouillage, mais l'enrouler dans un délai semble donner ce que vous cherchez:

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

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X