如何绑定到AngularJS的checkbox值列表?

我有几个checkbox:

<input type='checkbox' value="apple" checked> <input type='checkbox' value="orange"> <input type='checkbox' value="pear" checked> <input type='checkbox' value="naartjie"> 

我想绑定到我的控制器中的列表,只要checkbox被更改,控制器就会维护所有选中值的列表,例如['apple', 'pear']

ng-model似乎只能将单个checkbox的值绑定到控制器中的一个variables。

有没有另外的方法来做到这一点,我可以将四个checkbox绑定到控制器中的列表?

有两种方法可以解决这个问题。 使用一个简单的数组或一个对象数组。 每种解决scheme都有其优点和缺点。 下面你会发现每个案例之一。


用一个简单的数组作为input数据

HTML可能如下所示:

 <label ng-repeat="fruitName in fruits"> <input type="checkbox" name="selectedFruits[]" value="{{fruitName}}" ng-checked="selection.indexOf(fruitName) > -1" ng-click="toggleSelection(fruitName)" > {{fruitName}} </label> 

而适当的控制器代码将是:

 app.controller('SimpleArrayCtrl', ['$scope', function SimpleArrayCtrl($scope) { // Fruits $scope.fruits = ['apple', 'orange', 'pear', 'naartjie']; // Selected fruits $scope.selection = ['apple', 'pear']; // Toggle selection for a given fruit by name $scope.toggleSelection = function toggleSelection(fruitName) { var idx = $scope.selection.indexOf(fruitName); // Is currently selected if (idx > -1) { $scope.selection.splice(idx, 1); } // Is newly selected else { $scope.selection.push(fruitName); } }; }]); 

优点 :简单的数据结构和按名称切换很容易处理

缺点 :添加/删除很麻烦,因为必须pipe理两个列表(input和select)


用对象数组作为input数据

HTML可能如下所示:

 <label ng-repeat="fruit in fruits"> <!-- - Use `value="{{fruit.name}}"` to give the input a real value, in case the form gets submitted traditionally - Use `ng-checked="fruit.selected"` to have the checkbox checked based on some angular expression (no two-way-data-binding) - Use `ng-model="fruit.selected"` to utilize two-way-data-binding. Note that `.selected` is arbitrary. The property name could be anything and will be created on the object if not present. --> <input type="checkbox" name="selectedFruits[]" value="{{fruit.name}}" ng-model="fruit.selected" > {{fruit.name}} </label> 

而适当的控制器代码将是:

 app.controller('ObjectArrayCtrl', ['$scope', 'filterFilter', function ObjectArrayCtrl($scope, filterFilter) { // Fruits $scope.fruits = [ { name: 'apple', selected: true }, { name: 'orange', selected: false }, { name: 'pear', selected: true }, { name: 'naartjie', selected: false } ]; // Selected fruits $scope.selection = []; // Helper method to get selected fruits $scope.selectedFruits = function selectedFruits() { return filterFilter($scope.fruits, { selected: true }); }; // Watch fruits for changes $scope.$watch('fruits|filter:{selected:true}', function (nv) { $scope.selection = nv.map(function (fruit) { return fruit.name; }); }, true); }]); 

优点 :添加/删除非常简单

缺点 :稍微复杂一点的数据结构和按名称切换很麻烦,或者需要一个辅助方法


演示 : http : //jsbin.com/ImAqUC/1/

简单的解决scheme:

 <div ng-controller="MainCtrl"> <label ng-repeat="(color,enabled) in colors"> <input type="checkbox" ng-model="colors[color]" /> {{color}} </label> <p>colors: {{colors}}</p> </div> <script> var app = angular.module('plunker', []); app.controller('MainCtrl', function($scope){ $scope.colors = {Blue: true, Orange: true}; }); </script> 

http://plnkr.co/edit/U4VD61?p=preview

这里有一个快速的可重用的指令,似乎做你想要做的。 我只是把它叫做checkList 。 当checkbox更改时,它将更新数组,并在数组更改时更新checkbox。

 app.directive('checkList', function() { return { scope: { list: '=checkList', value: '@' }, link: function(scope, elem, attrs) { var handler = function(setup) { var checked = elem.prop('checked'); var index = scope.list.indexOf(scope.value); if (checked && index == -1) { if (setup) elem.prop('checked', false); else scope.list.push(scope.value); } else if (!checked && index != -1) { if (setup) elem.prop('checked', true); else scope.list.splice(index, 1); } }; var setupHandler = handler.bind(null, true); var changeHandler = handler.bind(null, false); elem.bind('change', function() { scope.$apply(changeHandler); }); scope.$watch('list', setupHandler, true); } }; }); 

这是一个控制器和一个视图,展示了如何使用它。

 <div ng-app="myApp" ng-controller='MainController'> <span ng-repeat="fruit in fruits"> <input type='checkbox' value="{{fruit}}" check-list='checked_fruits'> {{fruit}}<br /> </span> <div>The following fruits are checked: {{checked_fruits | json}}</div> <div>Add fruit to the array manually: <button ng-repeat="fruit in fruits" ng-click='addFruit(fruit)'>{{fruit}}</button> </div> </div> 
 app.controller('MainController', function($scope) { $scope.fruits = ['apple', 'orange', 'pear', 'naartjie']; $scope.checked_fruits = ['apple', 'pear']; $scope.addFruit = function(fruit) { if ($scope.checked_fruits.indexOf(fruit) != -1) return; $scope.checked_fruits.push(fruit); }; }); 

(button说明更改数组也会更新checkbox。)

最后,这里是一个在Plunker上的指令实例: http ://plnkr.co/edit/3YNLsyoG4PIBW6Kj7dRK?p=preview

 <input type='checkbox' ng-repeat="fruit in fruits" ng-checked="checkedFruits.indexOf(fruit) != -1" ng-click="toggleCheck(fruit)"> 

 function SomeCtrl ($scope) { $scope.fruits = ["apple, orange, pear, naartjie"]; $scope.checkedFruits = []; $scope.toggleCheck = function (fruit) { if ($scope.checkedFruits.indexOf(fruit) === -1) { $scope.checkedFruits.push(fruit); } else { $scope.checkedFruits.splice($scope.checkedFruits.indexOf(fruit), 1); } }; } 

基于这个线程的答案,我创build了涵盖所有情况的checklist-model指令:

  • 简单的基元数组
  • 对象数组(挑选id或整个对象)
  • 对象属性迭代

对于主题启动者来说,这将是:

 <label ng-repeat="fruit in ['apple', 'orange', 'pear', 'naartjie']"> <input type="checkbox" checklist-model="selectedFruits" checklist-value="fruit"> {{fruit}} </label> 

Vitaliy Potapov的GitHub上的checklist-model指令对我来说绝对有效(使用复杂的对象)。

我花了几个小时试图让其他解决scheme没有运气的工作。 伟大的工作,vitalets!

使用$index的string可以帮助使用选定值的散列表:

 <ul> <li ng-repeat="someItem in someArray"> <input type="checkbox" ng-model="someObject[$index.toString()]" /> </li> </ul> 

这样ng-model对象就会用代表索引的键来更新。

 $scope.someObject = {}; 

过了一段时间$scope.someObject应该看起来像这样:

 $scope.someObject = { 0: true, 4: false, 1: true }; 

这种方法不适用于所有的情况,但很容易实现。

既然你接受了一个没有使用清单的答案,我会假定我的评论问题的答案是“不,它不一定是一个清单”。 我也有这样的印象,可能是因为HTML服务器端的问题,因为在你的示例HTML中存在“checked”(如果使用ng-model来build模你的checkbox,这将不再需要)。

无论如何,当我问这个问题的时候,我想到了这一点,假设你正在生成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初始设置某些checkbox。

小提琴 。

我已经调整了Yoshi公认的答案来处理复杂的对象(而不是string)。

HTML

 <div ng-controller="TestController"> <p ng-repeat="permission in allPermissions"> <input type="checkbox" ng-checked="selectedPermissions.containsObjectWithProperty('id', permission.id)" ng-click="toggleSelection(permission)" /> {{permission.name}} </p> <hr /> <p>allPermissions: | <span ng-repeat="permission in allPermissions">{{permission.name}} | </span></p> <p>selectedPermissions: | <span ng-repeat="permission in selectedPermissions">{{permission.name}} | </span></p> </div> 

JavaScript的

 Array.prototype.indexOfObjectWithProperty = function(propertyName, propertyValue) { for (var i = 0, len = this.length; i < len; i++) { if (this[i][propertyName] === propertyValue) return i; } return -1; }; Array.prototype.containsObjectWithProperty = function(propertyName, propertyValue) { return this.indexOfObjectWithProperty(propertyName, propertyValue) != -1; }; function TestController($scope) { $scope.allPermissions = [ { "id" : 1, "name" : "ROLE_USER" }, { "id" : 2, "name" : "ROLE_ADMIN" }, { "id" : 3, "name" : "ROLE_READ" }, { "id" : 4, "name" : "ROLE_WRITE" } ]; $scope.selectedPermissions = [ { "id" : 1, "name" : "ROLE_USER" }, { "id" : 3, "name" : "ROLE_READ" } ]; $scope.toggleSelection = function toggleSelection(permission) { var index = $scope.selectedPermissions.indexOfObjectWithProperty('id', permission.id); if (index > -1) { $scope.selectedPermissions.splice(index, 1); } else { $scope.selectedPermissions.push(permission); } }; } 

工作示例: http : //jsfiddle.net/tCU8v/

另一个简单的指令可能是:

 var appModule = angular.module("appModule", []); appModule.directive("checkList", [function () { return { restrict: "A", scope: { selectedItemsArray: "=", value: "@" }, link: function (scope, elem) { scope.$watchCollection("selectedItemsArray", function (newValue) { if (_.contains(newValue, scope.value)) { elem.prop("checked", true); } else { elem.prop("checked", false); } }); if (_.contains(scope.selectedItemsArray, scope.value)) { elem.prop("checked", true); } elem.on("change", function () { if (elem.prop("checked")) { if (!_.contains(scope.selectedItemsArray, scope.value)) { scope.$apply( function () { scope.selectedItemsArray.push(scope.value); } ); } } else { if (_.contains(scope.selectedItemsArray, scope.value)) { var index = scope.selectedItemsArray.indexOf(scope.value); scope.$apply( function () { scope.selectedItemsArray.splice(index, 1); }); } } console.log(scope.selectedItemsArray); }); } }; }]); 

控制器:

 appModule.controller("sampleController", ["$scope", function ($scope) { //#region "Scope Members" $scope.sourceArray = [{ id: 1, text: "val1" }, { id: 2, text: "val2" }]; $scope.selectedItems = ["1"]; //#endregion $scope.selectAll = function () { $scope.selectedItems = ["1", "2"]; }; $scope.unCheckAll = function () { $scope.selectedItems = []; }; }]); 

而HTML:

 <ul class="list-unstyled filter-list"> <li data-ng-repeat="item in sourceArray"> <div class="checkbox"> <label> <input type="checkbox" check-list selected-items-array="selectedItems" value="{{item.id}}"> {{item.text}} </label> </div> </li> 

我还包括一个Plunker: http ://plnkr.co/edit/XnFtyij4ed6RyFwnFN6V?p=preview

看看这个指令,有效地pipe理checkbox的列表。 我希望它适合你。 CheckList模型

我认为最简单的解决办法是使用'select'和'multiple'指定:

 <select ng-model="selectedfruit" multiple ng-options="v for v in fruit"></select> 

否则,我认为你将不得不处理列表来构造列表(通过$watch()模型数组绑定与checkbox)。

有一种方法可以直接在数组上工作,并通过ng-model-options="{ getterSetter: true }"同时使用ng-model。

诀窍是在你的ng模型中使用getter / setter函数。 这样,您可以使用一个数组作为您的真实模型,并在input模型中“假”布尔值:

 <label ng-repeat="fruitName in ['apple', 'orange', 'pear', 'naartjie']"> <input type="checkbox" ng-model="fruitsGetterSetterGenerator(fruitName)" ng-model-options="{ getterSetter: true }" > {{fruitName}} </label> 
 $scope.fruits = ['apple', 'pear']; // pre checked $scope.fruitsGetterSetterGenerator = function(fruitName){ return function myGetterSetter(nowHasFruit){ if (nowHasFruit !== undefined){ // Setter fruitIndex = $scope.fruits.indexOf(fruit); didHaveFruit = (fruitIndex !== -1); mustAdd = (!didHaveFruit && nowHasFruit); mustDel = (didHaveFruit && !nowHasFruit); if (mustAdd){ $scope.fruits.push(fruit); } if (mustDel){ $scope.fruits.splice(fruitIndex, 1); } } else { // Getter return $scope.user.fruits.indexOf(fruit) !== -1; } } } 

myGetterSetter如果数组很大,则不应使用此方法,因为myGetterSetter将被调用很多次。

有关更多信息,请参阅https://docs.angularjs.org/api/ng/directive/ngModelOptions

你不必编写所有的代码。 AngularJS将使模型和checkbox保持同步,只需使用ngTrueValue和ngFalseValue

Codepen在这里: http ://codepen.io/paulbhartzog/pen/kBhzn

代码片段:

 <p ng-repeat="item in list1" class="item" id="{{item.id}}"> <strong>{{item.id}}</strong> <input name='obj1_data' type="checkbox" ng-model="list1[$index].data" ng-true-value="1" ng-false-value="0"> Click this to change data value below </p> <pre>{{list1 | json}}</pre> 

我喜欢Yoshi的回答。 我增强了它,所以你可以使用多个列表相同的function。

 <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

如果在同一个表单上有多个checkbox

控制器代码

 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中(假设checkbox位于表格中每行的第一列)。

 <tr ng-repeat="item in fruits"> <td><input type="checkbox" ng-model="item.checked" ng-click="getChecked(item)"></td> <td ng-bind="fruit.name"></td> <td ng-bind="fruit.color"></td> ... </tr> 

controllers.js文件中:

 // The data initialization part... $scope.fruits = [ { name: ...., color:.... }, { name: ...., color:.... } ... ]; // The checked or not data is stored in the object array elements themselves $scope.fruits.forEach(function(item){ item.checked = false; }); // The array to store checked fruit items $scope.checkedItems = []; // Every click on any checkbox will trigger the filter to find checked items $scope.getChecked = function(item){ $scope.checkedItems = $filter("filter")($scope.fruits,{checked:true}); }; 

这是另一个解决scheme。 我的解决scheme的好处:

  • 它不需要任何额外的手表(这可能会影响性能)
  • 它不需要控制器中的任何代码保持清洁
  • 代码仍然有点短
  • 这是需要非常less的代码在多个地方重复使用,因为它只是一个指令

这是指令:

 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}}" /> 

这就是全部。 唯一的补充是checkbox-array-set属性。

你可以结合AngularJS和jQuery。 例如,你需要定义一个数组$scope.selected = []; ,在控制器中。

 <label ng-repeat="item in items"> <input type="checkbox" ng-model="selected[$index]" ng-true-value="'{{item}}'">{{item}} </label> 

你可以得到一个拥有所选项目的数组。 使用方法alert(JSON.stringify($scope.selected)) ,您可以检查选定的项目。

以下解决scheme似乎是一个不错的select,

 <label ng-repeat="fruit in fruits"> <input type="checkbox" ng-model="fruit.checked" ng-value="true" > {{fruit.fruitName}} </label> 

而在控制器模型中价值fruits就是这样

 $scope.fruits = [ { "name": "apple", "checked": true }, { "name": "orange" }, { "name": "grapes", "checked": true } ]; 
  <div ng-app='app' > <div ng-controller='MainCtrl' > <ul> <li ng-repeat="tab in data"> <input type='checkbox' ng-click='change($index,confirm)' ng-model='confirm' /> {{tab.name}} </li> </ul> {{val}} </div> </div> var app = angular.module('app', []); app.controller('MainCtrl',function($scope){ $scope.val=[]; $scope.confirm=false; $scope.data=[ { name:'vijay' }, { name:'krishna' },{ name:'Nikhil' } ]; $scope.temp; $scope.change=function(index,confirm){ console.log(confirm); if(!confirm){ ($scope.val).push($scope.data[index]); } else{ $scope.temp=$scope.data[index]; var d=($scope.val).indexOf($scope.temp); if(d!=undefined){ ($scope.val).splice(d,1); } } } }) 

从上面的Yoshi的post启发。 这是plnkr 。

 (function () { angular .module("APP", []) .controller("demoCtrl", ["$scope", function ($scope) { var dc = this dc.list = [ "Selection1", "Selection2", "Selection3" ] dc.multipleSelections = [] dc.individualSelections = [] // 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. dc.addOrRemove = 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) } } } }]) })() 
 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" ng-checked="dc.multipleSelections.indexOf(thing) > -1" ng-click="dc.addOrRemove(dc.multipleSelections, thing, true)" > {{thing}} </label> <p> dc.multipleSelections :- {{dc.multipleSelections}} </p> <hr> <h4>Individual Selections</h4> <label ng-repeat="thing in dc.list"> <input type="checkbox" ng-checked="dc.individualSelections.indexOf(thing) > -1" ng-click="dc.addOrRemove(dc.individualSelections, thing, false)" > {{thing}} </label> <p> dc.invidualSelections :- {{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> 

基于我在这里的另一个职位,我做了一个可重用的指令。

看看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数组和对象,它可以使用静态HTMLcheckbox,而不需要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 = []; }); 

一个简单的HTML只有这样做的方式:

 <input type="checkbox" ng-checked="fruits.indexOf('apple') > -1" ng-click="fruits.indexOf('apple') > -1 ? fruits.splice(fruits.indexOf('apple'), 1) : fruits.push('apple')"> <input type="checkbox" ng-checked="fruits.indexOf('orange') > -1" ng-click="fruits.indexOf('orange') > -1 ? fruits.splice(fruits.indexOf('orange'), 1) : fruits.push('orange')"> <input type="checkbox" ng-checked="fruits.indexOf('pear') > -1" ng-click="fruits.indexOf('pear') > -1 ? fruits.splice(fruits.indexOf('pear'), 1) : fruits.push('pear')"> <input type="checkbox" ng-checked="fruits.indexOf('naartjie') > -1" ng-click="fruits.indexOf('apple') > -1 ? fruits.splice(fruits.indexOf('apple'), 1) : fruits.push('naartjie')"> 

Using this example of the @Umur Kontacı, I think in using to catch selected data throughout another object/array, like a edit page.

Catch options at the database

在这里输入图像描述

Toggle a some option

在这里输入图像描述

As example, all colors json in below:

 { "colors": [ { "id": 1, "title": "Preto - #000000" }, { "id": 2, "title": "Azul - #005AB1" }, { "id": 3, "title": "Azul Marinho - #001A66" }, { "id": 4, "title": "Amarelo - #FFF100" }, { "id": 5, "title": "Vermelho - #E92717" }, { "id": 6, "title": "Verde - #008D2F" }, { "id": 7, "title": "Cinza - #8A8A8A" }, { "id": 8, "title": "Prata - #C8C9CF" }, { "id": 9, "title": "Rosa - #EF586B" }, { "id": 10, "title": "Nude - #E4CAA6" }, { "id": 11, "title": "Laranja - #F68700" }, { "id": 12, "title": "Branco - #FFFFFF" }, { "id": 13, "title": "Marrom - #764715" }, { "id": 14, "title": "Dourado - #D9A300" }, { "id": 15, "title": "Bordo - #57001B" }, { "id": 16, "title": "Roxo - #3A0858" }, { "id": 18, "title": "Estampado " }, { "id": 17, "title": "Bege - #E5CC9D" } ] } 

And 2 types of data object, array with one object and object containing two/more object data:

  • Two items selected catched at the database:

     [{"id":12,"title":"Branco - #FFFFFF"},{"id":16,"title":"Roxo - #3A0858"}] 
  • One item selected catched at the database:

     {"id":12,"title":"Branco - #FFFFFF"} 

And here, my javascript code:

 /** * Add this code after catch data of database. */ vm.checkedColors = []; var _colorObj = vm.formData.color_ids; var _color_ids = []; if (angular.isObject(_colorObj)) { // vm.checkedColors.push(_colorObj); _color_ids.push(_colorObj); } else if (angular.isArray(_colorObj)) { angular.forEach(_colorObj, function (value, key) { // vm.checkedColors.push(key + ':' + value); _color_ids.push(key + ':' + value); }); } angular.forEach(vm.productColors, function (object) { angular.forEach(_color_ids, function (color) { if (color.id === object.id) { vm.checkedColors.push(object); } }); }); /** * Add this code in your js function initialized in this HTML page */ vm.toggleColor = function (color) { console.log('toggleColor is: ', color); if (vm.checkedColors.indexOf(color) === -1) { vm.checkedColors.push(color); } else { vm.checkedColors.splice(vm.checkedColors.indexOf(color), 1); } vm.formData.color_ids = vm.checkedColors; }; 

My Html code:

 <div class="checkbox" ng-repeat="color in productColors"> <label> <input type="checkbox" ng-checked="checkedColors.indexOf(color) != -1" ng-click="toggleColor(color)"/> <% color.title %> </label> </div> <p>checkedColors Output:</p> <pre><% checkedColors %></pre> 

[Edit] Refactored code below:

 function makeCheckedOptions(objectOptions, optionObj) { var checkedOptions = []; var savedOptions = []; if (angular.isObject(optionObj)) { savedOptions.push(optionObj); } else if (angular.isArray(optionObj)) { angular.forEach(optionObj, function (value, key) { savedOptions.push(key + ':' + value); }); } angular.forEach(objectOptions, function (object) { angular.forEach(savedOptions, function (color) { if (color.id === object.id) { checkedOptions.push(object); } }); }); return checkedOptions; } 

And call new method as below:

 vm.checkedColors = makeCheckedOptions(productColors, vm.formData.color_ids); 

而已!

I think the following way is more clear and useful for nested ng-repeats. Check it out on Plunker .

Quote from this thread :

 <html ng-app="plunker"> <head> <title>Test</title> <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.4/angular.min.js"></script> </head> <body ng-controller="MainCtrl"> <div ng-repeat="tab in mytabs"> <h1>{{tab.name}}</h1> <div ng-repeat="val in tab.values"> <input type="checkbox" ng-change="checkValues()" ng-model="val.checked"/> </div> </div> <br> <pre> {{selected}} </pre> <script> var app = angular.module('plunker', []); app.controller('MainCtrl', function ($scope,$filter) { $scope.mytabs = [ { name: "tab1", values: [ { value: "value1",checked:false }, { value: "value2", checked: false }, { value: "value3", checked: false }, { value: "value4", checked: false } ] }, { name: "tab2", values: [ { value: "value1", checked: false }, { value: "value2", checked: false }, { value: "value3", checked: false }, { value: "value4", checked: false } ] } ] $scope.selected = [] $scope.checkValues = function () { angular.forEach($scope.mytabs, function (value, index) { var selectedItems = $filter('filter')(value.values, { checked: true }); angular.forEach(selectedItems, function (value, index) { $scope.selected.push(value); }); }); console.log($scope.selected); }; }); </script> </body> </html> 

Here is the jsFillde link for the same, http://jsfiddle.net/techno2mahi/Lfw96ja6/ .

This uses the directive which is available for download at http://vitalets.github.io/checklist-model/ .

This is the good to have directive as your application will need this functionality much often.

代码如下:

HTML:

 <div class="container"> <div class="ng-scope" ng-app="app" ng-controller="Ctrl1"> <div class="col-xs-12 col-sm-6"> <h3>Multi Checkbox List Demo</h3> <div class="well"> <!-- ngRepeat: role in roles --> <label ng-repeat="role in roles"> <input type="checkbox" checklist-model="user.roles" checklist-value="role"> {{role}} </label> </div> <br> <button ng-click="checkAll()">check all</button> <button ng-click="uncheckAll()">uncheck all</button> <button ng-click="checkFirst()">check first</button> <div> <h3>Selected User Roles </h3> <pre class="ng-binding">{{user.roles|json}}</pre> </div> <br> <div><b/>Provided by techno2Mahi</b></div> </div> 

JavaScript的

 var app = angular.module("app", ["checklist-model"]); app.controller('Ctrl1', function($scope) { $scope.roles = [ 'guest', 'user', 'customer', 'admin' ]; $scope.user = { roles: ['user'] }; $scope.checkAll = function() { $scope.user.roles = angular.copy($scope.roles); }; $scope.uncheckAll = function() { $scope.user.roles = []; }; $scope.checkFirst = function() { $scope.user.roles.splice(0, $scope.user.roles.length); $scope.user.roles.push('guest'); }; }); 

I suggest using the AngularJS module Dropdown Multiselect .

I've put an array in the controller.

 $scope.statuses = [{ name: 'Shutdown - Reassessment Required' }, { name: 'Under Construction' }, { name: 'Administrative Cancellation' }, { name: 'Initial' }, { name: 'Shutdown - Temporary' }, { name: 'Decommissioned' }, { name: 'Active' }, { name: 'SO Shutdown' }] 

On the markup I've put something like following

 <div ng-repeat="status in $scope.statuses"> <input type="checkbox" name="unit_status" ng-model="$scope.checkboxes[status.name]"> {{status.name}} <br> </div> {{$scope.checkboxes}} 

The output was the following, in the controller I just needed to check whether its true or false; true for checked, absent/false for unchecked.

 { "Administrative Cancellation":true, "Under Construction":true, "Shutdown - Reassessment Required":true, "Decommissioned":true, "Active":true } 

希望这可以帮助。