У меня есть директива, используемая с select
. Он гарантирует, что выбранный объект, который должен быть select
имеет свойство.
bxUi.directive('bxHasOwnProperty', function () {
return {
require: 'ngModel',
link: function (scope, element, attrs, modelCtrl) {
function validate(viewValue) {
var prop = attrs.bxHasOwnProperty;
if (viewValue && prop && viewValue[prop] && viewValue[prop] !== "") {
modelCtrl.$setValidity('required', true);
} else {
modelCtrl.$setValidity('required', false);
}
return viewValue;
}
modelCtrl.$parsers.unshift(validate);
modelCtrl.$formatters.push(validate);
}
};
});
Пример использования будет:
<select name="city" ng-model="city" ng-options="c.name for c in vm.cities" bx-has-own-property="name"></select>
Таким образом, если пользователь выбирает город без имени, required
проверка не будет выполнена.
То, что я не уверен, что я сделал правильно, состоит в том, что синтаксический анализатор и валидатор используют ту же реализацию, в частности, что для $setValidity
используется $setValidity
. Это работает, но я не уверен, что это правильно. Я думал о полном удалении modelCtrl.$formatters.push(validate);
, но когда я это сделал, есть побочный эффект. Если я настроил модель в контроллере на город без имени (например {}
), required
валидатор не установлен, и я не вижу обратной связи с интерфейсом.
Вы можете вызвать $setValidity
в $setValidity
$parsers/$formatters
$setValidity
. Однако в большинстве случаев должно быть достаточно использовать modelCtrl.$validators
modelCtrl.$asyncValidators
и modelCtrl.$asyncValidators
которые будут автоматически вызывать $setValidity
.
Попробуй это:
bxUi.directive('bxHasOwnProperty', function () {
return {
require: 'ngModel',
link: function (scope, element, attrs, modelCtrl) {
modelCtrl.$validators.required = function (modelValue, viewValue) {
var prop = attrs.bxHasOwnProperty;
return (viewValue && prop && viewValue[prop] && viewValue[prop] !== "");
}
}
};
});