我正在构建一个 Angular Directive(指令),其中我有两个数字输入,它们一起代表一个年龄范围。
我想要实现的是能够通过以下方式使用该指令:
<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>
每次用户在输入中输入任何内容时,我都希望检查输入的范围是否正确:
- 两个年龄都应该是数字
- 两个人的年龄都应该在 18 到 80 岁之间
- 最小年龄 <= 最大年龄
到目前为止 ng-model-options="{allowInvalid: true}"
将让我的指令中的 ngChange 函数被触发,以防输入的任何年龄不在所需的年龄范围内(18-80) - 这样我可以进行一些检查并设置输入错误(如果有)并显示它。
我的问题是,如果最初输入的年龄不是数字,则不会调用 ngChange:它将无法进行错误检查,因此不会显示任何错误。在这种情况下,如何在不更改输入 type="number"
的情况下调用我的 ngChange 函数?
编辑:Jsfiddle 添加: http://jsfiddle.net/afkf96qh/
最佳答案
经过一天的努力弄清楚发生了什么,我终于实现了我正在寻找的行为。
首先,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()"
是我初始化 ageRange
的方式ngModel 中的变量 $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 ...>
中输入了一个值例如,它不是数字...绑定(bind)模型的值仍然是 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
触发。
关于javascript - Angular : how to fire ngChange when input type ="number" but not entered a number,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42390510/