ng-click으로 확인란을 클릭해도 모델이 업데이트되지 않습니다.


85

확인란을 클릭하고 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;

   };
}]);

Angular 1.2 RCx가있는 Broken Fiddle- http: //jsfiddle.net/supercobra/ekD3r/

- / 각도 1.0.0 승 fidddle 작업 http://jsfiddle.net/supercobra/8FQNw/


3
또한 1.2+에 지금은 각도 업데이트했는지 나에게 깨진
ac360

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 년

이런 전구, 배트맨! 나는 내가 완전히 다른 일을하고 있다고 생각했지만 이것만큼이나 간단하다는 것이 밝혀졌다.
Adam Marshall

1
매우 유용한 답변입니다! 한 각도 문서 -1
neurix

preventDefault에 이벤트 데이터가 필요한 경우 어떻게해야합니까?
user1943442 dec


9

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

이 솔루션은 여전히 ​​최고입니다!
Ellisan

8

사용하지 않는 이유

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

또는 또 다른 해결책은 todo.doneng-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

6

ng-model을 ng-checked로 대체하면 나를 위해 작동합니다.


내가 원했던 것. 감사!
Isaac

여기에서 사용 가능한 모든 솔루션에서 나를 위해 일했습니다.
thatzprem

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 컨트롤러와 새 범위를 만드는 입력 사이의 다른 지시문 때문입니다. select가 값을 쓸 때 가장 최근 범위까지 기록하므로 멀리있는 부모가 아닌이 범위에 기록합니다.

가장 좋은 방법은 절대로 범위의 변수에 직접 바인딩하지 않는 것입니다. ng-model 것입니다. 이것은 ngmodel에 항상 "점"을 포함하는 것으로도 알려져 있습니다. 이에 대한 더 자세한 설명은 John의이 비디오를 확인하십시오.

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

해결 방법 : https://groups.google.com/forum/#!topic/angular/7Nd_me5YrHU


#t=5m08s전체 비디오를 볼 필요가 없도록 YouTube 링크에 점프 마커를 제공하면 좋을 것 입니다. 참조 mattcutts.com/blog/link-to-youtube-minute-second
폴커 E.에게

0

난 그냥 교체 ng-modelng-checked그것은 나를 위해 일했습니다.

이 문제는 내 각도 버전을 1.2.28에서1.4.9

또한 ng-change여기에서 문제가 발생 하는지 확인 하십시오. 나는 ng-change그것을 작동시키기 위해 내 몸을 제거 해야했습니다.


-1
.task{ng:{repeat:'task in model.tasks'}}
  %input{type:'checkbox',ng:{model:'$parent.model.tasks[$index].enabled'}}
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.