自定义表单validation指令来比较两个字段

我是一个angular色的新手,我在angular度的formsvalidation指令如何工作的绊脚石。

我知道我可以很容易地添加指令到单个字段 ,但我试图添加一个validation,它将比较两个表单字段 (这两个都是模型的元素)。

这是一个表单框架:

<form name="edit_form" > <input name="min" type="number" ng-model="field.min"/> <input name="max" type="number" ng-model="field.max"/> </form> <div class="error" ng-show="edit_form.min.$dirty || edit_form.max.$dirty"> <small class="error" ng-show="(what goes here?)"> Min cannot exceed max </small> </div> 

总之,我想编写一个指令,并使用它来显示/隐藏这个small.error如果minmax都有值,但min > max 。 我怎样才能访问一个指令内的两个领域? 是一个指令是这个工作的正确工具?

许多方法去皮肤猫。

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

用法:

 <input name="min" type="number" ng-model="field.min" lower-than="{{field.max}}" /> <span class="error" ng-show="form.min.$error.lowerThan"> Min cannot exceed max. </span> 

你不需要任何指示。 只需将“最小”值分配给最小值即可。 喜欢:

 <input name="min" type="number" ng-model="field.min"/> <input name="max" type="number" ng-model="field.max" min=" {{ field.min }}"/> 

而且你不需要任何定制。
更多:你可以做min=" {{ field.min + 1}}"

简单的比较会适合你吗?

 <small class="error" ng-show="field.min > field.max"> 

如果你的情况是这样,我认为一个指令是一个矫枉过正的问题。 如果您对包含应用程序逻辑的视图感觉不舒服,则可以使用控制器的function将其导出:

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

和模板:

 <small class="error" ng-show="isMinMaxInalid()"> 

对我来说,除了反馈信息之外,我需要将该字段定义为无效,防止提交。 所以我收集了一些方法,比如@thestewie的方法,用视图configuration来收集date比较的解决scheme。 我希望能够汇总所提出的解决scheme。

代码在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; } }; } }; }) ; 

我的版本的指令:

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

你可以看看https://github.com/nelsonomuto/angular-ui-form-validation

这提供了一个预先configuration了一个API的指令,将范围及其模型展示给你的validation器函数。

这里是一个与你的具体用例的蹲点: http ://plnkr.co/edit/S0rBlS?p=preview

指令validation器的语法如下例所示: { 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;
} }