模型值不在选项中时,AngularJS select不会出错 [英] AngularJS select doesn't error when model value not in options
问题描述
角度1.4.8.
我有2个字母的美国州代码的标记:
I have this markup for 2-letter US state codes:
<div class="form-group" ng-class="{'has-error': form.licenseState.$invalid }">
<label for="licenseState" class="control-label">License State</label>
<select name="licenseState" id="licenseState" class="form-control" required
ng-model="ctrl.student.License.State"
ng-options="key as key for (key, value) in ctrl.licenseFormats">
</select>
</div>
当模型值加载为空白时,这正确地给了我一个错误.
This properly gives me an error when the model value is loaded as blank.
但是,当将模型值作为不在列表中的值(错误数据)加载时,它不会出错.
However, when the model value is loaded as a value not in the list (bad data), it does not error.
考虑到结果是各级错误信息,这种情况使我感到困惑.用户看到一个看似有效的空白值(尽管required
属性).模型会看到与用户不同的值,即使有效值列表中没有该值,该值也似乎是有效的.
The situation baffles me considering the result is misinformation at all levels. User sees a blank value which appears to be valid (despite required
attribute). Model sees a different value from user which appears to be valid even though it's absent from the valid values list.
我错过了什么吗?是否有适当的方法(规范角度)来触发表单验证错误?
Am I missing something? Is there a proper (canonical angular) way to make this trigger a form validation error?
更新
基于@ paul147的答案,我最终得到了这个可重用的指令,用于根据列表验证模型值.
Based on the answer from @paul147, I ended up with this reusable directive for validating a model value against a list.
m.directive('validValues', function() {
return {
scope: {
validValues: '='
},
restrict: 'A',
require: 'ngModel',
link: function (scope, element, attributes, ngModel) {
var values = angular.isArray(scope.validValues)
? scope.validValues
: Object.keys(scope.validValues);
ngModel.$validators.validValues = function (modelValue) {
return values.indexOf(modelValue) !== -1;
}
}
}
});
示例用法:
<select name="licenseState" required valid-values="ctrl.licenseFormats"
ng-model="ctrl.student.License.State"
ng-options="key as key for (key, value) in ctrl.licenseFormats">
</select>
我简要地探讨了直接从select元素获取选项的方法,但是ngOptions将值以自定义格式放置. F.ex string:AL
(实际上是一个查找键)的值表示AL
.进一步的讨论此处.最终,如果我像上面那样使用有效值的冗余声明(在这种情况下为ctrl.licenseFormats
)来执行该指令,则可以更轻松地重用该指令.
I briefly explored getting the options directly from the select element, but ngOptions puts the values in a custom format. F.ex string:AL
(which is actually a lookup key) for the value of AL
. Further discussion here. Ultimately, the directive is more reusable with less effort if I just do it as above with the redundant declaration of valid values (ctrl.licenseFormats
in this case).
推荐答案
要触发ngModel指令中的错误,您可以做的一件事是在ngModel的$ validators中添加一个自定义验证器.
One thing you can do to trigger errors on the ngModel directive is to add a custom validator to the ngModel's $validators.
ngModel的值在每次更改时都会通过$ validators传递,并且如果验证器返回false,则会引发错误.
The ngModel's value is passed through the $validators whenever it changes, and an error is raised if the validator returns false.
一个示例实现是将自定义指令添加到模型的元素,并在该指令内定义验证器:
An example implementation is to add a custom directive to the model's element, and define the validator inside that directive:
这是一个带有示例的插件: http://plnkr.co/edit/m6OygVR2GyMOXTTVTuhf? p =预览
Here's a plunkr with a working example: http://plnkr.co/edit/m6OygVR2GyMOXTTVTuhf?p=preview
// markup
<select name="licenseState" id="licenseState" class="form-control" required
ng-model="student.License.State"
ng-options="key as value for (key, value) in licenseFormats"
check-state
license-formats="licenseFormats">
// in the controller
$scope.licenseFormats = {
'OR': 'Oregon',
'WA': 'Washington',
};
// the directive
app.directive('checkState', function() {
return {
scope: {
licenseFormats: '='
},
restrict: 'A',
require: 'ngModel',
link: function(scope, element, attributes, ngModel) {
// defining the validator here
ngModel.$validators.state = function(modelValue) {
return Object.keys(scope.licenseFormats).indexOf(modelValue) > -1;
}
}
}
});
这篇关于模型值不在选项中时,AngularJS select不会出错的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!