Việc nhấp vào hộp kiểm với ng-click không cập nhật kiểu máy


85

Nhấp vào hộp kiểm và gọi ng-click: mô hình không được cập nhật trước khi ng-click khởi động, do đó giá trị hộp kiểm được trình bày sai trong giao diện người dùng:

Điều này hoạt động trong AngularJS 1.0.7 và dường như bị hỏng trong 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}}

và bộ điều khiển:

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;

   };
}]);

Broken Fiddle w / Angular 1.2 RCx - http://jsfiddle.net/supercobra/ekD3r/

Làm việc fidddle w / Angular 1.0.0 - http://jsfiddle.net/supercobra/8FQNw/


3
Tôi cũng bị hỏng vì tôi đã cập nhật Angular lên 1.2+
ac360 5/12/13

Cũng bị hỏng trong v1.2.24.
Vincent P

Câu trả lời:


165

Thay đổi thì sao

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

đến

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

Từ tài liệu :

Đánh giá biểu thức đã cho khi người dùng thay đổi đầu vào. Biểu thức không được đánh giá khi thay đổi giá trị đến từ mô hình.

Lưu ý, chỉ thị này yêu cầu ngModelphải có mặt.


3
điều này cũng dường như bị phá vỡ trong phiên bản 1.2.7
JvdBerg

Thần đèn, Người dơi! Tôi đã nghĩ rằng tôi đã làm một điều gì đó khác hoàn toàn sai, nhưng hóa ra lại đơn giản như thế này.
Adam Marshall

1
Câu trả lời rất hữu ích! +1 Angular doc -1
neurix

nếu bạn cần dữ liệu sự kiện để ngăn chặn Default thì sao?
user1943442,


9

Thứ tự mà ng-clickng-modelsẽ được thực hiện là không rõ ràng (vì cả hai đều không được đặt rõ ràng priority). Giải pháp ổn định nhất cho điều này là tránh sử dụng chúng trên cùng một phần tử.

Ngoài ra, bạn có thể không muốn hành vi mà các ví dụ hiển thị; bạn muốn checkboxphản hồi các nhấp chuột vào văn bản nhãn hoàn chỉnh , không chỉ hộp kiểm. Do đó, giải pháp sạch nhất sẽ là bọc input(with ng-model) bên trong một label(with ng-click):

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

Ví dụ làm việc: http://jsfiddle.net/b3NLH/1/


Cảm ơn rất nhiều! Đây là giải pháp duy nhất phù hợp với tôi!
DaniCE

Giải pháp này vẫn là tốt nhất!
Ellisan

8

Tại sao bạn không sử dụng

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

Hoặc một giải pháp khác là đặt lệnh todo.donegọi lại ng-click bên trong và chỉ sử dụng 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
Xem câu trả lời của @kakoni, tôi đã sử dụng ng-change thay vì ng-click và thời gian hoạt động rất tốt. Điều này cho phép bạn giữ ràng buộc hai chiều và cách tiếp cận rõ ràng hơn nhiều.
Michael Moser

6

Việc thay thế ng-model bằng ng-check có tác dụng với tôi.


Chỉ những gì tôi muốn. Cảm ơn!
Isaac

Chỉ làm việc cho tôi từ tất cả các giải pháp có sẵn ở đây.
thatzprem

2

Đây là một loại hack nhưng gói nó trong thời gian chờ dường như để đạt được những gì bạn đang tìm kiếm:

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

Thứ tự giữa ng-modelng-clickdường như là khác nhau và đó là điều bạn có thể không nên dựa vào. Thay vào đó, bạn có thể làm điều gì đó như sau:

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

Và kịch bản của bạn:

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;

   };
}]);

Điều khác biệt ở đây là bất cứ khi nào bạn nhấp vào một hộp, nó sẽ đặt hộp đó là "hiện tại" và sau đó hiển thị các giá trị đó trong chế độ xem. http://jsfiddle.net/QeR7y/


0

Thông thường điều này là do một chỉ thị khác nằm giữa ng-controller và đầu vào của bạn đang tạo một phạm vi mới. Khi select viết ra giá trị của nó, nó sẽ ghi nó lên phạm vi gần đây nhất, vì vậy nó sẽ ghi nó vào phạm vi này thay vì cha mẹ ở xa hơn.

Cách tốt nhất là không bao giờ liên kết trực tiếp với một biến trên phạm vi trong một ng-model , điều này còn được gọi là luôn bao gồm một "dấu chấm" trong ngmodel của bạn. Để được giải thích rõ hơn về điều này, hãy xem video này của John:

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

Giải pháp từ: https://groups.google.com/forum/#!topic/angular/7Nd_me5YrHU


Sẽ thật tuyệt nếu bạn cung cấp điểm đánh dấu bước nhảy #t=5m08strong liên kết YouTube của mình, vì vậy bạn không cần phải xem toàn bộ video. Xem mattcutts.com/blog/link-to-youtube-minute-second
Volker E.

0

Tôi chỉ cần thay thế ng-modelbằng ng-checkedvà nó làm việc cho tôi.

Vấn đề này là khi tôi cập nhật phiên bản góc của tôi từ 1.2.28đến1.4.9

Ngoài ra, hãy kiểm tra xem bạn ng-changecó đang gây ra bất kỳ vấn đề nào ở đây không. Tôi cũng đã phải xóa bỏ của mình ng-changeđể làm cho nó hoạt động.


-1
.task{ng:{repeat:'task in model.tasks'}}
  %input{type:'checkbox',ng:{model:'$parent.model.tasks[$index].enabled'}}
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.