我做了这个指令来验证一个数字是否在一个范围内:
app.directive('nkNumber', function(){
return {
scope: {
max: '=nkMax',
min: '=nkMin'
},
require: 'ngModel',
restrict: 'A',
link: function($scope, iElm, iAttrs, controller) {
function validate(value){
if (angular.isDefined(value)){
value = parseInt(value);
if ($scope.max){
var max = parseInt($scope.max);
controller.$setValidity('nkMax', value < max)
}
if ($scope.min){
var min = parseInt($scope.min);
controller.$setValidity('nkMin', value > min)
}
}
return value;
}
controller.$parsers.push(validate);
controller.$formatters.push(validate);
}
};
});
验证工作正常,但是当我更改输入值时,我的模型不会更新。
为什么会这样?我该如何解决?
答案 0 :(得分:4)
您可能正在使用1.2.x之前的角度版本。较旧版本的角度处理隔离范围不一致,通常会将其他指令吞入隔离范围。这就是你的情况。
ng-model作用于你的nk-number指令的隔离范围,所以它将它的值写入这个私有范围而不是外部范围。
如果您使用1.2.x版本的角度,隔离范围不会像这样混合,所以事情应该按预期工作。
如果要保留较旧版本的角度,修复程序就是不要对此特定指令使用隔离范围。
通常,除非您的指令具有模板,否则使用隔离范围几乎总是一个坏主意。如果你的指令没有自己的模板,那么使用隔离范围几乎是不合理的,并且可能导致你遇到的那类问题。
以下是没有隔离范围的指令编写示例:
app.directive('nkNumber', function($parse){
return {
require: 'ngModel',
restrict: 'A',
link: function($scope, iElm, iAttrs, controller) {
function validate(value){
var max = $scope.$eval(iAttrs.nkMax);
var min = $scope.$eval(iAttrs.nkMin);
if (angular.isDefined(value)){
value = parseInt(value);
if (max){
max = parseInt(max);
controller.$setValidity('nkMax', value < max)
}
if ($scope.min){
min = parseInt(min);
controller.$setValidity('nkMin', value > min)
}
}
return value;
}
controller.$parsers.push(validate);
controller.$formatters.push(validate);
}
};
});
请注意,如果没有隔离范围,您需要在$scope.$eval()
和nkMax
属性上使用nkMin
。
这实际上是编写此指令的更好方法,并且适用于所有版本的angular。