Validação não acionada quando dados vinculam os atributos min / max de input de um número

Eu tenho vários campos de input numéricos que têm valores de atributos min e max que dependem da lógica em outro lugar no meu aplicativo AngularJS, mas quando usando ligações de dados dentro desses atributos eles não são mais validados pelo Angular, no entanto, a validação HTML 5 ainda aparece para selecioná-los acima.

var myApp = angular.module('myApp', []); function FirstCtrl($scope) { $scope.min = 10; $scope.max = 20; } 
 

Versão ao vivo: http://jsfiddle.net/kriswillis/bPUVH/2/

Como você pode ver, a validação ainda é tratada bem no HTML / CSS (Bootstrap), pois ambos os campos ficam vermelhos quando inválidos, no entanto, o botão de envio (tratado pelo Angular) não é desabilitado quando o segundo campo é inválido. Além disso, não há propriedades min e max no myForm.two.$error Como existem no myForm.one.$error .

Alguém pode ver onde estou indo errado?

Aparentemente, não podemos usar {{}} s (ou seja, interpolação) para os campos min e max . Eu olhei para o código-fonte e achei o seguinte:

 if (attr.min) { var min = parseFloat(attr.min); 

$interpolate não é chamado, apenas parseFloat , então você precisa especificar uma string parecida com um número para min e max .

Eu escrevi diretivas para preencher a lacuna, ng-min e ng-max:

http://jsfiddle.net/g/s5gKC/

 var app = angular.module('app', []); function isEmpty(value) { return angular.isUndefined(value) || value === '' || value === null || value !== value; } app.directive('ngMin', function() { return { restrict: 'A', require: 'ngModel', link: function(scope, elem, attr, ctrl) { scope.$watch(attr.ngMin, function(){ ctrl.$setViewValue(ctrl.$viewValue); }); var minValidator = function(value) { var min = scope.$eval(attr.ngMin) || 0; if (!isEmpty(value) && value < min) { ctrl.$setValidity('ngMin', false); return undefined; } else { ctrl.$setValidity('ngMin', true); return value; } }; ctrl.$parsers.push(minValidator); ctrl.$formatters.push(minValidator); } }; }); app.directive('ngMax', function() { return { restrict: 'A', require: 'ngModel', link: function(scope, elem, attr, ctrl) { scope.$watch(attr.ngMax, function(){ ctrl.$setViewValue(ctrl.$viewValue); }); var maxValidator = function(value) { var max = scope.$eval(attr.ngMax) || Infinity; if (!isEmpty(value) && value > max) { ctrl.$setValidity('ngMax', false); return undefined; } else { ctrl.$setValidity('ngMax', true); return value; } }; ctrl.$parsers.push(maxValidator); ctrl.$formatters.push(maxValidator); } }; }); angular.bootstrap(document.body, ['app']); 

Angular parece agora suportar ng-min e ng-max para uso sem a necessidade de escrever suas próprias diretivas. Veja este violino que está usando Angular 1.4.2.

Eu também escrevi uma diretiva personalizada para isso:

Demonstração de trabalho: http://plnkr.co/edit/BJ98ZR?p=preview

 .directive('validateRange', ['$parse', function($parse) { function link($scope, $element, $attrs, ngModel) { var attrRange, range = []; function validate(value) { var validMin = true, validMax = true; if (typeof range[0] === 'number') { ngModel.$setValidity('min', value >= range[0]); validMin = value >= range[0]; } if (typeof range[1] === 'number') { ngModel.$setValidity('max', value <= range[1]); validMax = value <= range[1]; } return validMin && validMax ? value : undefined; } attrRange = $attrs.validateRange.split(/,/); range[0] = $parse(attrRange[0] || '')($scope); range[1] = $parse(attrRange[1] || '')($scope); $scope.$watchCollection('[' + $attrs.validateRange + ']', function(values) { range = values; validate(ngModel.$viewValue); }); ngModel.$parsers.unshift(validate); ngModel.$formatters.unshift(validate); } return { link: link, require: 'ngModel' }; }]); 

Exemplo de uso:

 
Min Value: Value: Max Value:
 myform.minvalue.$error {{ myform.minvalue.$error }} myform.value.$error {{ myform.value.$error }} myform.maxvalue.$error {{ myform.maxvalue.$error }} 

Eu enfrento o mesmo problema. obteve sucesso usando esta diretiva:

 angular.module('tech').directive('maximum', ['$parse', function($parse) { return { restrict: 'A', require: '?ngModel', link: function(scope, element, attrs, ctrl) { if (!ctrl) return; attrs.maximum = true; var checkMax = function(n) { if (!n) return; var actualValue = ctrl.$viewValue; var maxValue = attrs.maximum; if (parseInt(actualValue) > parseInt(maxValue)) { ctrl.$setValidity('maximum', false); } else { ctrl.$setValidity('maximum', true); } }; scope.$watch(attrs.ngModel, checkMax); //attrs.$observe('ngModel', remind); attrs.$observe('maximum', checkMax); } } } ]); 

Eu tenho essa solução deste site. para todo o código você pode ir para este site