禁止在angularJS中取消选中所有复选框

4
我正在使用AngularJS指令来创建复选框列表checklist-model,但我需要始终保留至少一个复选框被选中。 我已经通过添加if语句修改了checklist-model.js
watch if(current.length > 1)

在移除检查之前:

scope.$watch(attrs.ngModel, function(newValue, oldValue) {
  if (newValue === oldValue) { 
    return;
  } 
  var current = getter(scope.$parent);
  if (angular.isFunction(setter)) {
    if (newValue === true) {
      setter(scope.$parent, add(current, value, comparator));
    } else {
        if(current.length > 1)
        {
            setter(scope.$parent, remove(current, value, comparator));
        }
    }
  }

  if (checklistChange) {
    checklistChange(scope);
  }
});

问题在于 UI 已经变为未选中状态,但模型并没有改变。
是否有一个优雅的建议(最好不使用 JQuery)来将复选框更改回“已选中”状态,或者更好的是在它变为选中之前捕捉它?
JSfiddle 这里,尝试取消所有选中并查看当所有复选框都未选中时(我正在尝试防止这种情况),模型仍然保持不为空(这很好,但不够)。

1
我理解您的问题,但我认为您正在寻找错误的解决方案。如果用户想要禁用复选框,就让他这样做。否则,他必须选择另一个复选框,然后才能取消选中旧的复选框?您描述的这种行为是可怕的用户体验。保持简单,并使用表单验证来显示警告,如果他取消选中所有复选框并禁用提交按钮。 - Michael
4个回答

2
这可能是由于Angular和您使用的库的异步性质导致的。到目前为止,我找到的一些不太正规的解决方法如下(jsfiddle):创建一个事件来跟踪输入的点击并执行以下操作:
  $scope.onclick = function(evt) {
    if ($scope.user.roles.length === 1 && prevLength === 1) {
      evt.preventDefault();
    }

    prevLength = $scope.user.roles.length;
  };

然后将其添加到您的元素中。
 ng-click="onclick($event)"

我不是说它完美无缺,但它确实可行


2

我的一位同事建议,一旦只选择了一个复选框,就将其禁用,这样既可以防止模块的更改(因此指令甚至不需要更改),又可以提高用户体验,因为用户明白他无法取消选择:

     <input type="checkbox" checklist-model="user.roles" checklist-value="role.id" ng-disabled="shouldDisable(role.id)"> {{role.text}}

 $scope.shouldDisable = function(roleId) {
        var isDisabled = false;
        if($scope.user.roles.length === 1) {
            isDisabled = $scope.user.roles.indexOf(roleId) !== -1;
        }
        return isDisabled;
    }

请查看JSFiddle中的答案。

1

当前,该组件不支持此功能,但正在讨论实现 minlength/maxlength https://github.com/vitalets/checklist-model/issues/15,然后可以通过使用 checklist-minlength=1 来简单实现。

我还编辑了您的建议以实现 checklistBeforeChange。我将在下一批次中尝试处理这个问题。已在 v0.8.0 中实现。


实现于v0.8.0版本。 - Adrian Ber

0

使用array.some函数的更好版本,以下是@ozba的答案:

public atLeastOneRowEnabled(row): boolean {
        //at least one row is visible except the current line
        return !this.rows.some(rowIterator => rowIterator.logical_name !== row.logical_name && rowIterator.isVisible);
    }

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接