Direttiva di convalida dei moduli personalizzati per confrontare due campi

Sono un principiante inesperto, e inciampo su qualcosa su come funzionano le direttive di validazione della forma angular.

So che posso aggiungere abbastanza facilmente direttive a singoli campi , ma sto cercando di aggiungere una convalida che confronti due campi modulo (che sono entrambi elementi di un modello).

Ecco uno scheletro di forma:

Min cannot exceed max

In breve, voglio scrivere una direttiva e usarla per mostrare / hide questo small.error se min e max hanno entrambi valori ma min > max . Come posso accedere a entrambi i campi all’interno di una direttiva? Una direttiva è lo strumento giusto per questo lavoro?

Molti modi per pelle un gatto.

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.  

Non hai bisogno di alcuna direttiva. Basta assegnare il valore “min” del valore massimo al valore minimo. Piace:

   

E non hai bisogno di personalizzazione.
Altro: puoi fare min=" {{ field.min + 1}}"

Ti piacerebbe un semplice confronto?

  

Penso che una direttiva sarebbe eccessiva se il tuo caso è solo questo. Se non ti senti a tuo agio con la vista contenente la logica dell’applicazione, puoi esportarla in una funzione del controller:

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

E il modello:

  

Per me, al di là di un messaggio di feedback, avevo bisogno di definire il campo come non valido, impedendo l’invio. Così ho raccolto alcuni approcci, come l’approccio @thestewie, con una configurazione vista per raccogliere una soluzione per il confronto delle date. Spero di poter aggregare le soluzioni che sono state presentate.

Il codice è in 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; } }; } }; }) ; 

La mia versione della direttiva:

 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; }); } }; }); 

Puoi dare un’occhiata a https://github.com/nelsonomuto/angular-ui-form-validation

Questo fornisce una direttiva che è preconfigurata con una API che espone l’ambito e i suoi modelli alla funzione di validatore.

Ecco un plunker con il tuo caso d’uso specifico: http://plnkr.co/edit/S0rBlS?p=preview

La syntax per i validatori di direttive è come mostrato nell’esempio seguente: { 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;
} }