Diretiva de validação de formulário personalizado para comparar dois campos

Eu sou um novato angular e estou tropeçando em algo em como as diretivas de validação de formulário angular funcionam.

Eu sei que posso facilmente adicionar diretivas para campos individuais , mas estou tentando adicionar uma validação que irá comparar dois campos de formulário (ambos os quais são elementos de um modelo).

Aqui está um esqueleto de formulário:

    
Min cannot exceed max

Resumindo, eu quero escrever uma diretiva e usá-la para mostrar / ocultar esse small.error se min e max ambos tiverem valores, mas min > max . Como posso acessar os dois campos dentro de uma diretiva? Uma diretiva é a ferramenta certa para esse trabalho?

Muitas maneiras de esfolar um gato.

PLUNKER

 app.directive('lowerThan', [ function() { var link = function($scope, $element, $attrs, ctrl) { var validate = function(viewValue) { var comparisonModel = $attrs.lowerThan; if(!viewValue || !comparisonModel){ // It's valid because we have nothing to compare against ctrl.$setValidity('lowerThan', true); } // It's valid if model is lower than the model we're comparing against ctrl.$setValidity('lowerThan', parseInt(viewValue, 10) < parseInt(comparisonModel, 10) ); return viewValue; }; ctrl.$parsers.unshift(validate); ctrl.$formatters.push(validate); $attrs.$observe('lowerThan', function(comparisonModel){ // Whenever the comparison model changes we'll re-validate return validate(ctrl.$viewValue); }); }; return { require: 'ngModel', link: link }; } ]); 

Uso:

   Min cannot exceed max.  

Você não precisa de nenhuma diretiva. Apenas atribua o valor “min” de max para min-value. Gostar:

   

E você não precisa de nenhuma personalização.
Mais: você pode fazer min=" {{ field.min + 1}}"

Uma simples comparação serviria para você?

  

Eu acho que uma diretiva seria um exagero se o seu caso é apenas isso. Se você não se sentir confortável com a exibição que contém a lógica do aplicativo, poderá exportá-la em uma function do controlador:

 $scope.isMinMaxInalid = function() { return $scope.field.min > $scope.field.max; }; 

E o modelo:

  

Para mim, além de uma mensagem de feedback, eu precisava definir o campo como inválido, impedindo o envio. Por isso, reuni algumas abordagens, como a abordagem @thestewie, com uma configuração de visualização para reunir uma solução para comparação de datas. Espero que possa agregar as soluções apresentadas.

O código está em PLUNKER

 angular.module('MyApp') .directive('thisEarlierThan', function () { return { require: 'ngModel', restrict: 'A', link: function (scope, elem, attrs, ctrl) { var startDate, endDate; scope.$watch(attrs.ngModel, function (newVal, oldVal, scope) { startDate = newVal; check(); }); scope.$watch(attrs.thisEarlierThan, function (newVal, oldVal, scope) { endDate = newVal; check(); }); var check = function () { if (typeof startDate === 'undefined' || typeof endDate === 'undefined') { return; } if (!validate(startDate)) { startDate = new Date(startDate); if (!validate(startDate)) { return; } } if (!validate(endDate)) { endDate = new Date(endDate); if (!validate(endDate)) { return; } } if (startDate < endDate) { ctrl.$setValidity('thisEarlierThan', true); } else { ctrl.$setValidity('thisEarlierThan', false); } return; }; var validate = function (date) { if (Object.prototype.toString.call(date) === '[object Date]') { if (isNaN(date.getTime())) { return false; } else { return true; } } else { return false; } }; } }; }) ; 

Minha versão da diretiva:

 module.directive('greaterThan', function () { return { restrict: 'A', require: 'ngModel', link: function (scope, element, attributes, ngModelController) { var otherValue; scope.$watch(attributes.greaterThan, function (value) { otherValue = value; ngModelController.$validate(); }); ngModelController.$parsers.unshift(function (viewValue) { ngModelController.$setValidity('greaterThan', !viewValue || !otherValue || viewValue > otherValue); return viewValue; }); } }; }); 

Você pode dar uma olhada em https://github.com/nelsonomuto/angular-ui-form-validation

Isso fornece uma diretiva que é pré-configurada com uma API que expõe o escopo e seus modelos à sua function de validador.

Aqui está uma plunker com o seu caso de uso específico: http://plnkr.co/edit/S0rBlS?p=preview

A syntax para os validadores de diretivas é mostrada no exemplo abaixo: { errorMessage: 'Cannot contain the number one', validator: function (errorMessageElement, val, attr, element, model, modelCtrl){ /** * The model and modelCtrl(scope) are exposed in the validator function * */ return /1/.test(val) !== true;
} }
{ errorMessage: 'Cannot contain the number one', validator: function (errorMessageElement, val, attr, element, model, modelCtrl){ /** * The model and modelCtrl(scope) are exposed in the validator function * */ return /1/.test(val) !== true;
} }