这个指令可以改变一组checkbox的model格式,提交的时候格式为[x,y,z,...]
1 var dyDir = angular.module("dyDir", ['']) 15 //复选框指令 16 .directive('checklistModel', ['$parse', '$compile', function ($parse, $compile) { 17 // contains 18 function contains(arr, item, comparator) { 19 if (angular.isArray(arr)) { 20 for (var i = arr.length; i--;) { 21 if (comparator(arr[i], item)) { 22 return true; 23 } 24 } 25 } 26 return false; 27 } 28 29 // add 30 function add(arr, item, comparator) { 31 arr = angular.isArray(arr) ? arr : []; 32 if (!contains(arr, item, comparator)) { 33 arr.push(item); 34 } 35 return arr; 36 } 37 38 // remove 39 function remove(arr, item, comparator) { 40 if (angular.isArray(arr)) { 41 for (var i = arr.length; i--;) { 42 if (comparator(arr[i], item)) { 43 arr.splice(i, 1); 44 break; 45 } 46 } 47 } 48 return arr; 49 } 50 51 // http://stackoverflow.com/a/19228302/1458162 52 function postLinkFn(scope, elem, attrs) { 53 // exclude recursion, but still keep the model 54 var checklistModel = attrs.checklistModel; 55 attrs.$set("checklistModel", null); 56 // compile with `ng-model` pointing to `checked` 57 $compile(elem)(scope); 58 attrs.$set("checklistModel", checklistModel); 59 60 // getter / setter for original model 61 var getter = $parse(checklistModel); 62 var setter = getter.assign; 63 var checklistChange = $parse(attrs.checklistChange); 64 var checklistBeforeChange = $parse(attrs.checklistBeforeChange); 65 66 // value added to list 67 var value = attrs.checklistValue ? $parse(attrs.checklistValue)(scope.$parent) : attrs.value; 68 69 70 var comparator = angular.equals; 71 72 if (attrs.hasOwnProperty('checklistComparator')) { 73 if (attrs.checklistComparator[0] == '.') { 74 var comparatorExpression = attrs.checklistComparator.substring(1); 75 comparator = function (a, b) { 76 return a[comparatorExpression] === b[comparatorExpression]; 77 }; 78 79 } else { 80 comparator = $parse(attrs.checklistComparator)(scope.$parent); 81 } 82 } 83 84 // watch UI checked change 85 scope.$watch(attrs.ngModel, function (newValue, oldValue) { 86 if (newValue === oldValue) { 87 return; 88 } 89 90 if (checklistBeforeChange && (checklistBeforeChange(scope) === false)) { 91 scope[attrs.ngModel] = contains(getter(scope.$parent), value, comparator); 92 return; 93 } 94 95 setValueInChecklistModel(value, newValue); 96 97 if (checklistChange) { 98 checklistChange(scope); 99 }100 });101 102 function setValueInChecklistModel(value, checked) {103 var current = getter(scope.$parent);104 if (angular.isFunction(setter)) {105 if (checked === true) {106 setter(scope.$parent, add(current, value, comparator));107 } else {108 setter(scope.$parent, remove(current, value, comparator));109 }110 }111 112 }113 114 // declare one function to be used for both $watch functions115 function setChecked(newArr, oldArr) {116 if (checklistBeforeChange && (checklistBeforeChange(scope) === false)) {117 setValueInChecklistModel(value, scope[attrs.ngModel]);118 return;119 }120 scope[attrs.ngModel] = contains(newArr, value, comparator);121 }122 123 // watch original model change124 // use the faster $watchCollection method if it's available125 if (angular.isFunction(scope.$parent.$watchCollection)) {126 scope.$parent.$watchCollection(checklistModel, setChecked);127 } else {128 scope.$parent.$watch(checklistModel, setChecked, true);129 }130 }131 132 return {133 restrict: 'A',134 priority: 1000,135 terminal: true,136 scope: true,137 compile: function (tElement, tAttrs) {138 if ((tElement[0].tagName !== 'INPUT' || tAttrs.type !== 'checkbox') && (tElement[0].tagName !== 'MD-CHECKBOX') && (!tAttrs.btnCheckbox)) {139 throw 'checklist-model should be applied to `input[type="checkbox"]` or `md-checkbox`.';140 }141 142 if (!tAttrs.checklistValue && !tAttrs.value) {143 throw 'You should provide `value` or `checklist-value`.';144 }145 146 // by default ngModel is 'checked', so we set it if not specified147 if (!tAttrs.ngModel) {148 // local scope var storing individual checkbox model149 tAttrs.$set("ngModel", "checked");150 }151 152 return postLinkFn;153 }154 };155 }])
在html页面上使用方法如下:
1 2 3
这样的话,提交时,如果全选中,checkbox的model值为[1,2,3],是不是方便多了。