我有一个由ID数组支持的复选框列表。
<input type="checkbox" name="checkers" value="black" ng-model="board" />
<input type="checkbox" name="checkers" value="white" ng-model="board" />
该模型看起来像:
[ 'black', 'white' ]
因此,有许多“黑客”可以让人们按照自己的想法行事,甚至是指令checklist-model。
我的问题是我有一个使用ngModelController的$validators
进行动态验证的指令。该指令看起来像这样:
module.directive('validator', function($parse) {
return {
restrict: 'A',
require: '?ngModel',
link: function($scope, $element, $attrs, ngModelCtrl) {
var rules = $parse($attrs.validator)($scope);
ngModelCtrl.$validators.myValidator = function(val){
// this is simplified, real case is much more complex
if(rules.minSelections > 0){
return !(val.length <= rules.minSelections);
}
if(rules.required){
return !val.length;
}
}
}
}
});
我将它附在我的复选框上,如:
<input type="checkbox" name="checkers" val="black" validators="{ minSelections: 1 }" ng-model="board" />
<input type="checkbox" name="checkers" val="white" validators="{ minSelections: 1 }" ng-model="board" />
问题是val
验证中的myValidator
始终返回true / false。尽管采用了几种不同的方法甚至使用该指令,我似乎无法看到我需要的“实际”模型。注意:$ validators在点击该指令之前运行。
有人有任何建议吗?
答案 0 :(得分:0)
我最终创建了自己的checkbox指令并手动触发验证。
如果您查看下面的内容,您可以看到我如何观看该集合,如果值已更改,我提交值并手动重新触发验证。
继承人的代码:
define(['angular'], function (angular) {
// Use to style checkboxes, bind checkboxes to arrays, and run validators on checkboxes
// Modified from: https://github.com/bkuhl/angular-form-ui/tree/master/src/directives/checkBox
var module = angular.module('components.checkbox', []);
/**
* <check-box ng-model="isChecked()"></check-box>
* Required attribute: ng-model="[expression]"
* Optional attribute: value="[expression]"
*/
module.directive('checkBox', function () {
return {
replace: true,
restrict: 'E',
scope: {
'externalValue': '=ngModel',
'value': '&'
},
require: 'ngModel',
template: function (el, attrs) {
var html = '<div class="ngCheckBox' + ((angular.isDefined(attrs.class)) ? ' class="'+attrs.class+'"' : '') + '">'+
'<span ng-class="{checked: isChecked}">' +
'<input type="checkbox" ng-model="isChecked"' + ((angular.isDefined(attrs.id)) ? ' id="'+attrs.id+'"' : '') + '' + ((angular.isDefined(attrs.name)) ? ' name="'+attrs.name+'"' : '') + '' + ((angular.isDefined(attrs.required)) ? ' name="'+attrs.required+'"' : '') + '/>'+
'</span>'+
'</div>';
return html;
},
controller: function ($scope) {
if (angular.isArray($scope.externalValue)) {
$scope.isChecked = $scope.externalValue.indexOf($scope.value()) >= 0;
} else {
$scope.isChecked = !!$scope.externalValue;
}
$scope.$watch('isChecked', function (newValue, oldValue) {
if (angular.isDefined(newValue) && angular.isDefined(oldValue)) {
//add or remove items if this is an array
if (angular.isArray($scope.externalValue)) {
var index = $scope.externalValue.indexOf($scope.value());
if(newValue) {
if( index < 0 ) $scope.externalValue.push($scope.value());
} else {
if( index >= 0 ) $scope.externalValue.splice(index, 1);
}
} else {
//simple boolean value
$scope.externalValue = newValue;
}
}
});
},
link: function ($scope, $elm, $attrs, ngModel) {
$scope.$watchCollection('externalValue', function(newVal) {
if (newVal.length) {
ngModel.$setTouched();
ngModel.$commitViewValue();
ngModel.$validate();
}
});
}
};
});
return module;
});