我正在建立一个角度指令,我有两个数字输入,两者一起代表一个年龄范围。
我想要实现的是能够以下列方式使用此指令:
<input-age-range
name="ageRange"
ng-model="filterUpdateVM.ageRange">
</input-age-range>
<span ng-if="myCtrlVM.form.ageRange.$error.ageRange">
Please, enter a valid age range.
</span>
并且能够在输入的年龄范围不正确时显示自定义错误。
我的指令html模板看起来像这样:
<div class="col-md-3">
<input type="number"
class="form-control"
placeholder="Minimum age"
name="ageMin"
min="18"
max="80"
ng-change="checkAndValidateAgeRange()"
ng-model="ageRange.ageMin"
ng-model-options="{allowInvalid: true}">
</div>
<div class="col-md-3">
<input type="number"
class="form-control"
placeholder="Maximum age"
name="ageMax"
min="18"
max="80"
ng-change="checkAndValidateAgeRange()"
ng-model="ageRange.ageMax"
ng-model-options="{allowInvalid: true}">
</div>
每次用户在输入中输入任何内容时,我都希望检查输入的范围是否正确:
到目前为止ng-model-options="{allowInvalid: true}"
将让我的指令中的ngChange函数被触发,以防任何输入的年龄不在期望的年龄范围(18-80)之间 - 这样我可以做一些检查和设置如果有任何输入错误并显示它。
我的问题是,如果首先输入的年龄不是数字,则不会调用ngChange:它将无法执行错误检查,因此不会显示任何错误。如何在不改变输入type="number"
的情况下调用我的ngChange函数?
编辑:Jsfiddle补充道: http://jsfiddle.net/afkf96qh/
答案 0 :(得分:3)
最后,经过一天的努力弄清楚发生了什么,我实现了我一直在寻找的行为。
首先,ng-model-options="{allowInvalid: true}"
无法解决我的问题,所以我从输入中删除了它。我的指令html模板现在看起来像这样:
<div class="col-md-3">
<input type="number"
class="form-control"
placeholder="Minimum age"
name="ageMin"
min="18"
max="80"
ng-model="ageRange.ageMin"
ng-change="checkAndValidateAgeRange()">
</div>
<div class="col-md-3">
<input type="number"
class="form-control"
placeholder="Maximum age"
name="ageMax"
min="18"
max="80"
ng-model="ageRange.ageMax"
ng-change="checkAndValidateAgeRange()">
</div>
导致未触发ng-change="checkAndValidateAgeRange()"
的问题是我在 ngModel ageRange
函数中初始化$render
变量的方式:
angular
.module('myModule')
.directive('myDirective', myDirective);
function myDirective() {
var directive = {
templateUrl: 'myTemplate.html',
restrict: 'E',
require: ['^form', 'ngModel'],
link: linkFunc
};
return directive;
/////////
function linkFunc(scope, element, attrs, ctrls) {
scope.form = ctrls[0];
scope.ageRange = {};
scope.checkAndValidateAgeRange = checkAndValidateAgeRange;
var ngModel = ctrls[1];
ngModel.$render = getAgeRange;
function checkAndValidateAgeRange() {
// fired when the model changes
};
// $render function
function getAgeRange() {
scope.ageRange.ageMin = ngModel.$viewValue.ageMin;
scope.ageRange.ageMax = ngModel.$viewValue.ageMax;
};
};
};
在某些情况下,传递给指令的 ngModel 对象的属性 - ageMin
和ageMax
- 可能都是undefined
。
我们都知道当我们输入type="[whatever]"
,min="18"
或max="80"
等限制时会发生什么情况,并且输入中输入的数据不符合这些要求:它是在模型中设置为undefined
。
因此,如果上述属性最初传递给设置为undefined
的指令,并且您在<input type="number ...>
中输入了一个值,例如,它不是数字...绑定模型的值将会仍然是undefined
,因此模型中不会有任何更改,因为ng-change
不会触发。
我最终要做的就是将ageRange.ageMin
和ageRange.ageMax
初始化为null
,如果它们作为undefined
传递给我$render
功能:
ngModel.$render = getAgeRange;
// $render function
function getAgeRange() {
scope.ageRange.ageMin = ngModel.$viewValue.ageMin || null;
scope.ageRange.ageMax = ngModel.$viewValue.ageMax || null;
};
这样,当输入无效输入时,模型的属性值将从null
更改为undefined
,从而导致ng-change
触发。
答案 1 :(得分:0)
$scope.checkAndValidateAgeRange = function(name, model) {
if (name === 'ageMin') {
if (angular.isNumber(model)) {
if (model < $scope.age.min) {
$scope.minAgeMessage = 'You are under age';
} else if (model > $scope.age.max) {
$scope.minAgeMessage = 'You are too old';
} else {
$scope.minAgeMessage = '';
}
} else {
$scope.minAgeMessage = 'Enter Only Numbers';
$scope.ageRange.ageMin = null;
}
}
if (name === 'ageMax') {
if (angular.isNumber(model)) {
if (model <= $scope.ageRange.ageMin) {
$scope.maxAgeMessage = 'You are under age';
} else if (model > $scope.age.max) {
$scope.maxAgeMessage = 'You are too old';
} else {
$scope.maxAgeMessage = '';
}
} else {
$scope.maxAgeMessage = 'Enter Only Numbers';
$scope.ageRange.ageMax = null;
}
}
}
答案 2 :(得分:-1)