I have a controller getting a list of users and a view listing them, along with a checkbox for displaying and setting whether they are active...
.controller('StaffCtrl', ['StaffService', function(StaffService) {
var self = this;
self.staff = StaffService.query();
self.activeUpdate = function(person){
StaffService.update({id:person.id}, person);
};
}]);
<tr ng-repeat="person in staffCtrl.staff">
<td>{{ person.name_full }} </td>
<td><input type="checkbox" ng-checked="person.active" ng-model="person.active" ng-change="staffCtrl.activeUpdate(person)" ng-true-value="1" ng-false-value="0"></td>
</tr>
Clicking the checkbox once triggers activeUpdate
, the async call is made and the user updated, but within the view the check mark itself doesn't disappear from the checkbox (in latest Chrome and Firefox). If I click it again now the check mark disappears and activeUpdate
isn't called. If I click once more the check reappears and the call gets made all at the same time, always only when adding the check, removing it consistently takes 2 clicks!
What am I doing wrong?
Update: Sample JSON for the staff list (using curl to query the REST api...)
[
{
"active": 1,
"id": 1,
"name_first": "Ed",
"name_full": "Tech, Ed",
"name_last": "Tech",
"name_middle": null,
"uri": "/sips/api/staff/1",
"username": "admin"
},
{
"active": 1,
"id": 252,
"name_first": "test",
"name_full": "aatest, test",
"name_last": "aatest",
"name_middle": "something",
"uri": "/sips/api/staff/252",
"username": "testteacher"
},
...
]
Using ng-checked
and ng-model
together can conflict, they both want to set the actual checked state of the checkbox. Second, ng-true-value
and ng-false-value
seem to only work with strings. So when you are clicking to set the value, it changes person.active
from the number 1 to the string '1'
. That is also what causes the unchecking problem, the string "0" is a true
value so ng-checked
thinks the box should be checked but ng-model
does not.
And since ngTrueValue
only accepts constant expressions, I don't see an easy way to get it to do what you want with numbers for active
. (Angular Source)
You might be able to skip using ngModel
and instead use ngChecked
for display and ngClick
to update your property with a method plunker:
<input type="checkbox" ng-checked="person.active"
ng-click="updateActive(person)"</input>
JS:
self.updateActive = function(person) {
console.dir(person);
person.active = 1 - person.active;
}