我有一些复选框:
<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似乎只能将一个复选框的值绑定到控制器中的一个变量。
是否有其他方法可以将这四个复选框绑定到控制器中的列表?
如果在同一个表单上有多个复选框
控制器代码
vm.doYouHaveCheckBox = ['aaa', 'ccc', 'bbb'];
vm.desiredRoutesCheckBox = ['ddd', 'ccc', 'Default'];
vm.doYouHaveCBSelection = [];
vm.desiredRoutesCBSelection = [];
视图代码
<div ng-repeat="doYouHaveOption in vm.doYouHaveCheckBox">
<div class="action-checkbox">
<input id="{{doYouHaveOption}}" type="checkbox" value="{{doYouHaveOption}}" ng-checked="vm.doYouHaveCBSelection.indexOf(doYouHaveOption) > -1" ng-click="vm.toggleSelection(doYouHaveOption,vm.doYouHaveCBSelection)" />
<label for="{{doYouHaveOption}}"></label>
{{doYouHaveOption}}
</div>
</div>
<div ng-repeat="desiredRoutesOption in vm.desiredRoutesCheckBox">
<div class="action-checkbox">
<input id="{{desiredRoutesOption}}" type="checkbox" value="{{desiredRoutesOption}}" ng-checked="vm.desiredRoutesCBSelection.indexOf(desiredRoutesOption) > -1" ng-click="vm.toggleSelection(desiredRoutesOption,vm.desiredRoutesCBSelection)" />
<label for="{{desiredRoutesOption}}"></label>
{{desiredRoutesOption}}
</div>
</div>
既然你接受了一个没有使用列表的答案,我就假设我的评论问题的答案是“不,它不一定是一个列表”。我也有这样的印象,也许您正在租用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初始设置某些复选框。
小提琴。
根据我在这里的另一篇文章,我已经做了一个可重用的指令。
查看GitHub存储库
(function () {
angular
.module("checkbox-select", [])
.directive("checkboxModel", ["$compile", function ($compile) {
return {
restrict: "A",
link: function (scope, ele, attrs) {
// Defining updateSelection function on the parent scope
if (!scope.$parent.updateSelections) {
// Using splice and push methods to make use of
// the same "selections" object passed by reference to the
// addOrRemove function as using "selections = []"
// creates a new object within the scope of the
// function which doesn't help in two way binding.
scope.$parent.updateSelections = function (selectedItems, item, isMultiple) {
var itemIndex = selectedItems.indexOf(item)
var isPresent = (itemIndex > -1)
if (isMultiple) {
if (isPresent) {
selectedItems.splice(itemIndex, 1)
} else {
selectedItems.push(item)
}
} else {
if (isPresent) {
selectedItems.splice(0, 1)
} else {
selectedItems.splice(0, 1, item)
}
}
}
}
// Adding or removing attributes
ele.attr("ng-checked", attrs.checkboxModel + ".indexOf(" + attrs.checkboxValue + ") > -1")
var multiple = attrs.multiple ? "true" : "false"
ele.attr("ng-click", "updateSelections(" + [attrs.checkboxModel, attrs.checkboxValue, multiple].join(",") + ")")
// Removing the checkbox-model attribute,
// it will avoid recompiling the element infinitly
ele.removeAttr("checkbox-model")
ele.removeAttr("checkbox-value")
ele.removeAttr("multiple")
$compile(ele)(scope)
}
}
}])
// Defining app and controller
angular
.module("APP", ["checkbox-select"])
.controller("demoCtrl", ["$scope", function ($scope) {
var dc = this
dc.list = [
"selection1",
"selection2",
"selection3"
]
// Define the selections containers here
dc.multipleSelections = []
dc.individualSelections = []
}])
})()
label {
display: block;
}
<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet" href="style.css" />
</head>
<body ng-app="APP" ng-controller="demoCtrl as dc">
<h1>checkbox-select demo</h1>
<h4>Multiple Selections</h4>
<label ng-repeat="thing in dc.list">
<input type="checkbox" checkbox-model="dc.multipleSelections" checkbox-value="thing" multiple>
{{thing}}
</label>
<p>dc.multipleSelecitons:- {{dc.multipleSelections}}</p>
<h4>Individual Selections</h4>
<label ng-repeat="thing in dc.list">
<input type="checkbox" checkbox-model="dc.individualSelections" checkbox-value="thing">
{{thing}}
</label>
<p>dc.individualSelecitons:- {{dc.individualSelections}}</p>
<script data-require="jquery@3.0.0" data-semver="3.0.0" src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.0.0/jquery.js"></script>
<script data-require="angular.js@1.5.6" data-semver="1.5.6" src="https://code.angularjs.org/1.5.6/angular.min.js"></script>
<script src="script.js"></script>
</body>
</html>
看看这个:清单模型。
它可以使用JavaScript数组和对象,它可以使用静态HTML复选框,而不需要ng-repeat
<label><input type="checkbox" checklist-model="roles" value="admin"> Administrator</label>
<label><input type="checkbox" checklist-model="roles" value="customer"> Customer</label>
<label><input type="checkbox" checklist-model="roles" value="guest"> Guest</label>
<label><input type="checkbox" checklist-model="roles" value="user"> User</label>
JavaScript方面:
var app = angular.module("app", ["checklist-model"]);
app.controller('Ctrl4a', function($scope) {
$scope.roles = [];
});
这里还有另一个解决方案。我的解决方案的好处是:
它不需要任何额外的手表(这可能会影响性能)
它不需要控制器中的任何代码来保持干净
代码仍然有些短
它只需要很少的代码就可以在多个地方重用,因为它只是一个指令
下面是指令:
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属性。