角度:验证多个依赖字段
angular: Validate multiple dependent fields
假设我有以下(非常简单的)数据结构:
$scope.accounts = [{
percent: 30,
name: "Checking"},
{ percent: 70,
name: "Savings"}];
然后,我将以下结构作为表单的一部分:
<div ng-repeat="account in accounts">
<input type="number" max="100" min="0" ng-model="account.percent" />
<input type="text" ng-model="account.name" />
</div>
现在,我想验证每组帐户的百分比总和是否为 100,但我看到的大多数自定义指令示例仅涉及验证单个值。创建一次验证多个依赖字段的指令的惯用方法是什么?jquery中有相当多的解决方案,但我无法找到Angular的好来源。
编辑:我想出了以下自定义指令("共享"是原始代码"百分比"的同义词)。共享验证指令采用形式"{group: accounts, id: $index}"
的映射作为其值。
app.directive('shareValidate', function() {
return {
restrict: 'A',
require: 'ngModel',
link: function(scope, elem, attr, ctrl) {
ctrl.$parsers.unshift(function(viewValue) {
params = angular.copy(scope.$eval(attr.shareValidate));
params.group.splice(params.id, 1);
var sum = +viewValue;
angular.forEach(params.group, function(entity, index) {
sum += +(entity.share);
});
ctrl.$setValidity('share', sum === 100);
return viewValue;
});
}
};
});
这几乎有效,但无法处理字段无效的情况,但另一个字段中的后续更改使其再次有效。例如:
Field 1: 61
Field 2: 52
如果我将字段 2 降至 39,则字段 2 现在将有效,但字段 1 仍然无效。想法?
好的,以下工作(同样,"份额"是"百分比"):
app.directive('shareValidate', function () {
return {
restrict: 'A',
require: 'ngModel',
link: function(scope, elem, attr, ctrl) {
scope.$watch(attr.shareValidate, function(newArr, oldArr) {
var sum = 0;
angular.forEach(newArr, function(entity, i) {
sum += entity.share;
});
if (sum === 100) {
ctrl.$setValidity('share', true);
scope.path.offers.invalidShares = false;
}
else {
ctrl.$setValidity('share', false);
scope.path.offers.invalidShares = true;
}
}, true); //enable deep dirty checking
}
};
});
在 HTML 中,将属性设置为"共享验证",并将值设置为要监视的对象集。
你可以检查angularui库(ui-utility部分)。它有 ui 验证指令。
那么可以实现它的一种方法是
<input type="number" name="accountNo" ng-model="account.percent"
ui-validate="{overflow : 'checkOverflow($value,account)' }">
在控制器上创建基于帐户计算返回 true 或 false 的方法checkOverflow
。
我自己还没有尝试过,但想分享这个想法。也请阅读网站上提供的示例。
我有一个动态表单,我可以在我的表单上拥有可变数量的输入字段,我需要限制正在添加的输入控件的数量。
我无法轻松限制这些输入字段的添加,因为它们是由其他因素的组合生成的,因此如果输入字段的数量超过限制,我需要使表单无效。 我通过在控制器ctrl.myForm
中创建对表单的引用来做到这一点,然后每次动态生成输入控件(在我的控制器代码中),我都会进行限制检查,然后在表单上设置有效性,如下所示:ctrl.myForm.$setValidity("maxCount", false);
这很有效,因为验证不是由特定的输入字段决定的,而是由我的输入总数决定的。 如果您需要执行由多个字段的组合确定的验证,则相同的方法可能有效。
为了我的理智
.HTML
<form ng-submit="applyDefaultDays()" name="daysForm" ng-controller="DaysCtrl">
<div class="form-group">
<label for="startDate">Start Date</label>
<div class="input-group">
<input id="startDate"
ng-change="runAllValidators()"
ng-model="startDate"
type="text"
class="form-control"
name="startDate"
placeholder="mm/dd/yyyy"
ng-required
/>
</div>
</div>
<div class="form-group">
<label for="eEndDate">End Date</label>
<div class="input-group">
<input id="endDate"
ng-change="runAllValidators()"
ng-model="endDate"
type="text"
class="form-control"
name="endDate"
placeholder="mm/dd/yyyy"
ng-required
/>
</div>
</div>
<div class="text-right">
<button ng-disabled="daysForm.$invalid" type="submit" class="btn btn-default">Apply Default Dates</button>
</div>
.JS
'use strict';
angular.module('myModule')
.controller('DaysCtrl', function($scope, $timeout) {
$scope.initDate = new Date();
$scope.startDate = angular.copy($scope.initDate);
$scope.endDate = angular.copy($scope.startDate);
$scope.endDate.setTime($scope.endDate.getTime() + 6*24*60*60*1000);
$scope.$watch("daysForm", function(){
//fields are only populated after controller is initialized
$timeout(function(){
//not all viewalues are set yet for somereason, timeout needed
$scope.daysForm.startDate.$validators.checkAgainst = function(){
$scope.daysForm.startDate.$setDirty();
return (new Date($scope.daysForm.startDate.$viewValue)).getTime() <=
(new Date($scope.daysForm.endDate.$viewValue)).getTime();
};
$scope.daysForm.endDate.$validators.checkAgainst = function(){
$scope.daysForm.endDate.$setDirty();
return (new Date($scope.daysForm.startDate.$viewValue)).getTime() <=
(new Date($scope.daysForm.endDate.$viewValue)).getTime();
};
});
});
$scope.runAllValidators = function(){
//need to run all validators on change
$scope.daysForm.startDate.$validate();
$scope.daysForm.endDate.$validate();
};
$scope.applyDefaultDays = function(){
//do stuff
}
});
您可以定义仅负责此检查的单个指令。
<form>
<div ng-repeat="account in accounts">
<input type="number" max="100" min="0" ng-model="account.percent" />
<input type="text" ng-model="account.name" />
</div>
<!-- HERE IT IS -->
<sum-up-to-hundred accounts="accounts"></sum-up-to-hundred>
</form>
这是简单指令的代码。
app.directive('sumUpToHundred', function() {
return {
scope: {
accounts: '<'
},
require: {
formCtrl: '^form'
},
bindToController: true,
controllerAs: '$ctrl',
controller: function() {
var vm = this;
vm.$doCheck = function(changes) {
var sum = vm.accounts.map((a)=> a.percent).reduce((total, n)=> total + n);
if (sum !== 100) {
vm.formCtrl.$setValidity('sumuptohundred', false);
} else {
vm.formCtrl.$setValidity('sumuptohundred', true);
}
};
}
};
});
这是一个笨蛋。
- 如何隐藏&使用jQuery禁用依赖于另一个字段值的字段
- Rails 4-具有依赖字段Rails的条件JS
- yii2:依赖于Action的条件显示/显示字段
- Ember-自定义计算属性,用于检查是否存在所有依赖字段
- AngularJS,如何使UI依赖于哪个字段具有焦点
- 角度 - 依赖字段验证
- 轨道 4 - JS 用于具有简单形式的依赖字段
- 在 Reactjs 中创建依赖字段
- 角度:验证多个依赖字段
- 可以't访问require.js中的依赖对象字段-无法读取未定义的属性
- Knockout.js text相互依赖的输入字段
- Rivets.js属性依赖于几个字段
- 在Ember控制器中使用依赖注入字段
- 在依赖于另一个字段选择的窗体中隐藏表的某个部分
- AngularJS中带依赖字段的表单验证
- LiveCycle -多个计算依赖于选中的复选框和输入字段
- 两个相互依赖的选择字段
- 添加相互依赖的签出字段
- 添加额外的字段依赖于其他查询的查询结果在mongodb中,使用mongojs
- 在我的表单中创建依赖字段