不能在ng-repeat内的复选框上设置模型

时间:2017-05-12 19:34:56

标签: javascript angularjs

我有一行复选框,一次只能检查一个复选框,如果单击选中的复选框,其状态应该翻转。因此,如果选中它并单击它,则应取消选中,反之亦然。

模型

this.models = [
  {name: 'blah', defaulted: false},
  {name: 'fdsf', defaulted: false},
  ...
]

模板

<input 
  type="checkbox"
  ng-repeat="model in vm.models"
  ng-checked="model.defaulted === true" 
  ng-change="vm.setDefault($index)"
  ng-model="model.defaulted" />

a。这个没有用,型号没有更新

http://embed.plnkr.co/O275a9O7y60NuimFYdYi?show=preview

this.setDefault = (j) => this.models = this.models.map((m, i) => {
  return j === i 
    ? Object.assign({}, m, {defaulted: !m.defaulted}) 
    : Object.assign({}, m, {defaulted: false}) 
}) 

b。模型在此版本中正确更新,但您无法通过再次单击来取消选中复选框(因此示例中的!m.defaulted

http://embed.plnkr.co/MOBuN06R0hmcnpGu01Z7?show=preview

// this works, but now you can't uncheck a box that is checked
this.setDefault = (j) => this.models = this.models.map((m, i) => {
  return j === i 
    ? Object.assign({}, m, {defaulted: true}) 
    : Object.assign({}, m, {defaulted: false}) 
}) 

需要不使用无线电的解决方案

4 个答案:

答案 0 :(得分:2)

我不喜欢你使用index数组元素的方式。如果您对models集合应用任何过滤,则无效。相反,我建议您将当前选定的模型传递给setDefault函数,如下所示,并将当前模型标记为true,其他模型将设置为false。 此外,每次创建对象的新副本时都不需要使用Object.assign。相反,循环和修改现有的数组元素更有意义。

<input type="checkbox" 
  ng-change="vm.setDefault(model)"
  ng-model="model.defaulted" />

<强>代码

this.setDefault = (j) => {
    this.models.forEach(i => i.defaulted = i.defaulted && j.name === i.name);
} 

Demo Plunker

答案 1 :(得分:2)

您所要做的就是改变:

this.setDefault = (j) => this.models = this.models.map((m, i) => {
  return j === i 
    ? Object.assign({}, m, {defaulted: true}) 
    : Object.assign({}, m, {defaulted: false}) 
}) 

this.setDefault = (j) => this.models = this.models.map((m, i) => {
  return j === i 
    ? Object.assign({}, m, {defaulted: m.defaulted}) 
    : Object.assign({}, m, {defaulted: false}) 
}) 

通过将其更改为Object.assign({}, m, {defaulted: m.defaulted}),您可以切换当前所选/未选中复选框的状态。

编辑:请注意@ PankajParkar的答案更好,因为与我的答案不同,这只是解决主要问题,因为它不会覆盖{{1使用this.models的数组 - 这使得角度在Array.prototype.map()循环中重新渲染视图。

欢迎您接受他们的回答

答案 2 :(得分:0)

<强> HTML

<input name="foo" ng-change="vm.setDefault(opt)" ng-model="opt.defaulted" type="checkbox" ng-repeat="opt in vm.models" />

<强>的JavaScript

this.setDefault = function(opt) {
    this.models.forEach((val) => {
        if(opt != val) {
            val.defaulted = false;
        }
    });
};

收集了一些downvotes,但实际上效果很好。

https://plnkr.co/edit/BhE7XF?p=preview

答案 3 :(得分:0)

我说拧了它并使用了图标而不是复选框

<i
  ng-click="vm.setDefault($index)"
  ng-class="{'fa-circle-thin': model.defaulted === false, 'fa-circle': model.defaulted === true}"
  class="fa">
</i>

https://plnkr.co/edit/5dj865ew1dqUMM9cchrY?p=preview