Ng-tıklama ile bir onay kutusuna tıklamak modeli güncellemiyor


85

Bir onay kutusuna tıklamak ve ng-tıklama çağırmak: model, ng-tıklama başlamadan önce güncellenmez, bu nedenle onay kutusu değeri UI'de yanlış bir şekilde gösterilir:

Bu, AngularJS 1.0.7'de çalışıyor ve Angualar 1.2-RCx'te bozuk görünüyor.

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

ve denetleyici:

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;

   };
}]);

Kırık Keman, Açısal 1.2 RCx ile - http://jsfiddle.net/supercobra/ekD3r/

Angular 1.0.0 w / fidddle çalışmak - http://jsfiddle.net/supercobra/8FQNw/


3
Ayrıca Angular'ı 1.2+
ac360

Ayrıca v1.2.24'te kırılmıştır.
Vincent P

Yanıtlar:


165

Ne dersin

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

-e

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

Gönderen docs :

Kullanıcı girişi değiştirdiğinde verilen ifadeyi değerlendirin. Modelden değer değişikliği geldiğinde ifade değerlendirilmez.

Bu direktifin ngModelmevcut olması gerektiğini unutmayın .


3
bu da 1.2.7 sürümünde bozuk görünüyor
JvdBerg

Kutsal ampul, Batman! Tamamen yanlış başka bir şey yaptığımı sanıyordum ama bu kadar basit olduğu ortaya çıktı.
Adam Marshall

1
Çok faydalı cevap! +1 Angular doc -1
neurix

Varsayılanı önlemek için olay verilerine ihtiyacınız varsa?
user1943442


9

Uygulanacak ng-clickve ng-modeluygulanacak sıra belirsizdir (çünkü ikisi de açıkça belirtilmemiştir priority). Bunun için en kararlı çözüm, onları aynı eleman üzerinde kullanmaktan kaçınmak olacaktır.

Ayrıca, muhtemelen örneklerin gösterdiği davranışı istemezsiniz; yalnızca onay kutusuna değil checkbox, tam etiket metnine yapılan tıklamalara yanıt vermesini istiyorsunuz . Bu nedenle, en temiz çözüm, input(with ng-model) öğesini a label(with ng-click) içine sarmak olacaktır :

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

Çalışma örneği: http://jsfiddle.net/b3NLH/1/


Çok teşekkürler! Benim için işe yarayan tek çözüm bu!
DaniCE

Bu çözüm hala en iyisidir!
Ellisan

8

Neden kullanmıyorsun

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

Veya başka bir çözüm todo.done, ng-tıklama geri aramasının içini ayarlamak ve yalnızca ng-tıklama kullanmak olabilir.

<div ng-app="myApp" ng-controller="Ctrl">
<li  ng-repeat="todo in todos">
<input type='checkbox' ng-click='onCompleteTodo(todo)'>
    {{todo.text}} {{todo.done}}

ve

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

2
@Kakoni cevabına bakın, ng-tıklama yerine ng-değiştirme kullandım ve zamanlama harika çalışıyor. Bu, iki yönlü bağlamayı korumanıza izin verir ve çok daha temiz bir yaklaşımdır.
Michael Moser

6

Ng-modelini ng-check ile değiştirmek benim için çalışıyor.


Tam istediğim gibi. Teşekkürler!
Isaac

Burada mevcut tüm çözümlerden benim için çalıştı.
thatzprem

2

Bu bir çeşit hack ama zaman aşımına uğramak, aradığınız şeyi başarıyor gibi görünüyor:

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

Aradaki sıralama ng-modelve ng-clickfarklı görünüyor ve muhtemelen güvenmemeniz gereken bir şey. Bunun yerine şuna benzer bir şey yapabilirsiniz:

<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>

Ve senaryonuz:

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;

   };
}]);

Burada farklı olan, bir kutuyu her tıkladığınızda, bu kutuyu "mevcut" olarak ayarlayıp ardından bu değerleri görünümde görüntülemesidir. http://jsfiddle.net/QeR7y/


0

Genellikle bu, ng denetleyiciniz ile yeni bir kapsam oluşturan girdiniz arasındaki başka bir direktiften kaynaklanır. Select, değerini yazdığında, onu en son kapsama yazacak, böylece onu daha uzaktaki ebeveyn yerine bu kapsama yazacaktır.

En iyi uygulama, bir kapsamdaki bir değişkene asla doğrudan bağlanmamaktır ng-model, bu aynı zamanda ng modelinize her zaman bir "nokta" eklemek olarak da bilinir. Bunun daha iyi bir açıklaması için John'un şu videosuna bakın:

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

Çözüm: https://groups.google.com/forum/#!topic/angular/7Nd_me5YrHU


#t=5m08sYouTube bağlantınıza bir atlama işareti koyarsanız harika olur , böylece videonun tamamını izlemenize gerek kalmaz. Bkz mattcutts.com/blog/link-to-youtube-minute-second
Volker E.

0

Ben sadece yerini ng-modelile ng-checkedve bu benim için çalıştı.

Bu sorun, açısal sürümümü olarak 1.2.28olarak güncellediğim zamandı1.4.9

Ayrıca ng-changeburadan herhangi bir soruna neden olup olmadığını kontrol edin . ng-changeÇalışması için benim de çıkarmam gerekiyordu.


-1
.task{ng:{repeat:'task in model.tasks'}}
  %input{type:'checkbox',ng:{model:'$parent.model.tasks[$index].enabled'}}
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.