我有一些复选框:
<input type='checkbox' value="apple" checked>
<input type='checkbox' value="orange">
<input type='checkbox' value="pear" checked>
<input type='checkbox' value="naartjie">
我想绑定到我的控制器中的一个列表,这样每当一个复选框被更改时,控制器就会维护一个包含所有选中值的列表,例如,['apple', 'pear']。
Ng-model似乎只能将一个复选框的值绑定到控制器中的一个变量。
是否有其他方法可以将这四个复选框绑定到控制器中的列表?
这里还有另一个解决方案。我的解决方案的好处是:
它不需要任何额外的手表(这可能会影响性能)
它不需要控制器中的任何代码来保持干净
代码仍然有些短
它只需要很少的代码就可以在多个地方重用,因为它只是一个指令
下面是指令:
function ensureArray(o) {
var lAngular = angular;
if (lAngular.isArray(o) || o === null || lAngular.isUndefined(o)) {
return o;
}
return [o];
}
function checkboxArraySetDirective() {
return {
restrict: 'A',
require: 'ngModel',
link: function(scope, element, attrs, ngModel) {
var name = attrs.checkboxArraySet;
ngModel.$formatters.push(function(value) {
return (ensureArray(value) || []).indexOf(name) >= 0;
});
ngModel.$parsers.push(function(value) {
var modelValue = ensureArray(ngModel.$modelValue) || [],
oldPos = modelValue.indexOf(name),
wasSet = oldPos >= 0;
if (value) {
if (!wasSet) {
modelValue = angular.copy(modelValue);
modelValue.push(name);
}
} else if (wasSet) {
modelValue = angular.copy(modelValue);
modelValue.splice(oldPos, 1);
}
return modelValue;
});
}
}
}
最后就像这样使用它:
<input ng-repeat="fruit in ['apple', 'banana', '...']" type="checkbox" ng-model="fruits" checkbox-array-set="{{fruit}}" />
这就是全部了。唯一增加的是复选框-数组-set属性。
既然你接受了一个没有使用列表的答案,我就假设我的评论问题的答案是“不,它不一定是一个列表”。我也有这样的印象,也许您正在租用HTML服务器端,因为“checked”出现在您的示例HTML中(如果ng-model用于对复选框建模,则不需要这样做)。
不管怎样,这是我在问这个问题时想到的,也假设你正在生成HTML服务器端:
<div ng-controller="MyCtrl"
ng-init="checkboxes = {apple: true, orange: false, pear: true, naartjie: false}">
<input type="checkbox" ng-model="checkboxes.apple">apple
<input type="checkbox" ng-model="checkboxes.orange">orange
<input type="checkbox" ng-model="checkboxes.pear">pear
<input type="checkbox" ng-model="checkboxes.naartjie">naartjie
<br>{{checkboxes}}
</div>
ng-init允许服务器端生成的HTML初始设置某些复选框。
小提琴。
我喜欢Yoshi的回答。我增强了它,所以你可以对多个列表使用相同的函数。
<label ng-repeat="fruitName in fruits">
<input
type="checkbox"
name="selectedFruits[]"
value="{{fruitName}}"
ng-checked="selection.indexOf(fruitName) > -1"
ng-click="toggleSelection(fruitName, selection)"> {{fruitName}}
</label>
<label ng-repeat="veggieName in veggies">
<input
type="checkbox"
name="selectedVeggies[]"
value="{{veggieName}}"
ng-checked="veggieSelection.indexOf(veggieName) > -1"
ng-click="toggleSelection(veggieName, veggieSelection)"> {{veggieName}}
</label>
app.controller('SimpleArrayCtrl', ['$scope', function SimpleArrayCtrl($scope) {
// fruits
$scope.fruits = ['apple', 'orange', 'pear', 'naartjie'];
$scope.veggies = ['lettuce', 'cabbage', 'tomato']
// selected fruits
$scope.selection = ['apple', 'pear'];
$scope.veggieSelection = ['lettuce']
// toggle selection for a given fruit by name
$scope.toggleSelection = function toggleSelection(selectionName, listSelection) {
var idx = listSelection.indexOf(selectionName);
// is currently selected
if (idx > -1) {
listSelection.splice(idx, 1);
}
// is newly selected
else {
listSelection.push(selectionName);
}
};
}]);
http://plnkr.co/edit/KcbtzEyNMA8s1X7Hja8p?p=preview