禁止取消选中 angularJS 中的所有复选框
Disallow unchecking of all checkboxes in angularJS
我对复选框列表使用 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已经变成unchecked,而model没变
任何人都有关于如何将复选框更改回 "checked" 状态的优雅建议(最好没有 JQuery),或者更好地在它更改为选中之前抓住它?
JSfiddle here,尝试取消选中所有复选框并查看当复选框全部取消选中时(我试图阻止的)模型保持不为空(这很好但还不够)
这可能来自 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)"
我不是说它很完美,但它确实有效
我的一位同事建议在它是唯一选中的复选框时禁用它,这样你既可以防止更改模块(因此指令甚至不需要更改)并且用户体验更好知道他不能取消选中:
<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;
}
在 this JSfiddle
中查看答案
目前组件不支持这个,但是有讨论实现 minlength/maxlength https://github.com/vitalets/checklist-model/issues/15 然后就可以用 checklist-minlength=1
.[=13 简单实现了=]
我还编辑了您的实施提案 checklistBeforeChange
。我也会在下一批中尝试处理这个问题。在 v0.8.0 中实现。
@ozba 使用 array.some 函数回答的更好版本:
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);
}
我对复选框列表使用 AngularJS 指令 checklist-model 但我需要始终至少选中一个复选框。 我通过添加 if:
更改了 checklist-model.jswatch 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已经变成unchecked,而model没变
任何人都有关于如何将复选框更改回 "checked" 状态的优雅建议(最好没有 JQuery),或者更好地在它更改为选中之前抓住它?
JSfiddle here,尝试取消选中所有复选框并查看当复选框全部取消选中时(我试图阻止的)模型保持不为空(这很好但还不够)
这可能来自 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)"
我不是说它很完美,但它确实有效
我的一位同事建议在它是唯一选中的复选框时禁用它,这样你既可以防止更改模块(因此指令甚至不需要更改)并且用户体验更好知道他不能取消选中:
<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;
}
在 this JSfiddle
中查看答案目前组件不支持这个,但是有讨论实现 minlength/maxlength https://github.com/vitalets/checklist-model/issues/15 然后就可以用 checklist-minlength=1
.[=13 简单实现了=]
我还编辑了您的实施提案 checklistBeforeChange
。我也会在下一批中尝试处理这个问题。在 v0.8.0 中实现。
@ozba 使用 array.some 函数回答的更好版本:
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);
}