2015-03-17 15 views
13

Sto scrivendo un semplice controller AngularJS che tiene traccia del numero di checkbox selezionate. Cercando di evitare $scope.$watch e utilizzare invece ng-change per incrementare/decrementare il conteggio totale.

HTML:

<form ng-controller="MainCtrl"> 
    <table> 
    <tr ng-repeat="item in data"> 
     <td> 
     <input type="checkbox" 
      value="{{item.id}}" 
      ng-model="item.selected" 
      ng-change="updateTotal($event)"> &nbsp; {{item.name}} 
     </td> 
    </tr> 
    </table> 
    <p> 
     Total checked: {{totalSelected}} 
    </p> 
</form> 

controller frammento

$scope.updateTotal = function($event) { 

    var checkbox = $event.target; 

    if (checkbox.checked) { 
     $scope.totalSelected++; 
    } 
    else { 
     $scope.totalSelected--; 
    } 
} 

Continuo a ricevere un errore nel controller in cui tento di accedere $event.target:

TypeError: Cannot read property 'target' of undefined 

Ho creato un Plunk per ricreare: http://plnkr.co/edit/qPzETejmMHHZCQ2sV2Sk?p=info

Se qualcuno ha qualche idea o suggerimento sarei molto grato.

Grazie mille!

+2

@levi sia corretto. Ma più filosoficamente, evita "checkbox.checked" (o qualcosa di simile al DOM) nel controller. Invece manda il 'item' (o' item.selected'). – DRobinson

+0

@DRobinson Ha senso, grazie. Hai ragione con il tuo suggerimento di non accoppiarlo così strettamente al DOM. –

+0

@levi, se dobbiamo interrompere la propagazione dell'evento all'interno di 'ng-change', come possiamo ottenerlo? – Mak

risposta

41

ng-change la funzione non consente di passare $event come variabile.

Da un collaboratore AngularJS github repo ufficiale:

ng-cambiamento non è una direttiva per la gestione dell'evento cambiamento (mi rendo conto che questo è fonte di confusione dato il nome), ma in realtà è, invece notificata quando ngModelController. $ viene chiamato $ setViewValue() e il valore cambia (poiché ng-change aggiunge un listener alla raccolta $ viewChangeListeners di ). Quindi questo è come previsto.

Si può leggere di più su di esso ng-change doesn't get the $event argument

Come è possibile risolvere il requisito?

Basta passare item.selected alla funzione ng-change e controllarne il valore.

HTML

<input type="checkbox" 
     value="{{item.id}}" 
     ng-model="item.selected" 
     ng-change="updateTotal(item.selected)"> &nbsp; {{item.name}} 

controller

$scope.updateTotal = function(item_selected) { 

    if (item_selected) { 
     $scope.totalSelected++; 
    } 
    else { 
     $scope.totalSelected--; 
    } 
} 

AGGIORNATO

È possibile verificare qui, in questo plnkr

+0

Sembra una soluzione molto elegante e soddisfa il suggerimento di DRobinson di non utilizzare checkbox.checked.Lo proveremo quando torno a casa, grazie! –

+0

@PhilipTenn Ho preparato un plnkr per te, controlla la mia risposta. – levi

+0

e se volessimo separarlo con il valore del modello? –