复选框上的 ng-change 需要点击 2 次

ng-change on checkbox requires 2 clicks

我有一个控制器获取用户列表和一个列出他们的视图,以及一个用于显示和设置他们是否处于活动状态的复选框...

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

点击复选框一次触发 activeUpdate,进行异步调用并更新用户,但在视图中复选标记本身并没有从复选框中消失(在最近的 Chrome 和火狐)。如果我现在再次单击它,复选标记就会消失并且不会调用 activeUpdate。如果我再次单击检查再次出现并且同时进行所有调用,总是仅在添加检查时,删除它始终需要点击 2 次!

我做错了什么?

更新:员工列表示例 JSON(使用 curl 查询 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"
    },
    ...
]

一起使用ng-checkedng-model会发生冲突,它们都想设置复选框的实际选中状态。其次,ng-true-valueng-false-value 似乎只适用于字符串。因此,当您单击以设置值时,它会将 person.active 从数字 1 更改为字符串 '1'。这也是导致取消选中问题的原因,字符串“0”是一个 true 值,因此 ng-checked 认为应该选中该框,但 ng-model 不。

而且由于 ngTrueValue 只接受常量表达式,我看不出有什么简单的方法可以让它根据 active 的数字执行您想要的操作。 (Angular Source)

您可以跳过使用 ngModel,而是使用 ngChecked 进行显示,并使用 ngClick 使用方法 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;
}

如上所述,如果您忘记 true、false、0 和 1 并且只考虑两个字符串“0”和“1”,Angular 最有效(在这种情况下)——尽管一旦您意识到它有效好的字符串,你可以使用我猜的任何东西 'yes/no' 'true/false'

你只需要使用这个:

ng-model = "object.property"
ng-true=value="'1'" // note the string
ng-false-value = "'0'"
ng-checked = "object.property=='1'"

然后它就可以完美运行,不需要其他解决方法。 如果需要,请使用 ng-change 作为通知,但不要使用它来更改 object.property 的状态,否则当然会发生冲突

您可以像下面这样简单地更改,其余模型将自动执行。 你也不需要 ng-checked 因为你已经在使用 ng-model.

<input type="checkbox"  ng-model="person.active" ng-change="staffCtrl.activeUpdate(person)" ng-true-value="'1'" ng-false-value="'0'">