我正在尝试验证没有重复值的表单。 我有一个网站包含一个IP地址列表。 我可以添加许多地址,但它们应该是唯一的。
HTML:
<div class="col-sm-6">
<ul style="list-style-type: none;-webkit-padding-start: 0px;margin-bottom:0px">
<li ng-repeat="ip in site.ips track by $index | orderBy: '+ip.ip_adress'" style="margin-bottom:0px">
<ng-form name="ipForm">
<div class="input-group" style="margin-top:5px" ng-class="{ 'has-error' : !ipForm.ip_adress.$error.duplicate && ipForm.ip_adress.$invalid && !ipForm.ip_adress.$pristine }">
<input type="text" class="form-control input-sm" name="ip_adress"
ng-pattern='/^([0-9]{1,3})[.]([0-9]{1,3})[.]([0-9]{1,3})[.]([0-9]{1,3})$/'
style="display: inline;"
ng-model="ip.ip_adress"
placeholder="{{translate('config.sites.msg.site.ip.adress')}}"
required />
<div class="input-group-addon">
<i class="glyphicon glyphicon-remove-circle" ng-click="removeIp(site, ip, $index)"></i>
</div>
</div>
</ng-form>
</li>
</ul>
</div>
我也试过ng-change:"verifyDuplicate()"
,这里是 JS
$scope.verifyDuplicate = function() {
var sorted, i;
sorted = $scope.sites[0].ips.sort(function (a, b) {
if (a.ip_adress > b.ip_adress) return 1;
if (a.ip_adress < b.ip_adress) return -1;
return 0;
});
for(i = 0; i < $scope.sites.ips.length; i++) {
sorted[i].isDuplicate = ((sorted[i-1] && sorted[i-1].ip_adress == sorted[i].ip_adress) || (sorted[i+1] && sorted[i+1].ip_adress == sorted[i].ip_adress));
}
}
这会引发错误:Cannot read property 'ips' of undefined
。
我也试过这个例子,但它不起作用。
有什么建议吗?
答案 0 :(得分:1)
如果您想要控制输入的validity
,必须构建指令,那么您的表单将变为$invalid
。
这是一个可以在代码中复制的简单演示:
angular.module('app', ['ngMessages'])
.controller('mainCtrl', function($scope) {
$scope.site = {};
$scope.site.ips = ['172.16.254.1', '255.255.255.255', '111.111.111.111']
})
.directive('duplicate', function() {
return {
restrict: 'A',
scope: {
index: '@',
array: '@'
},
require: 'ngModel',
link: function(scope, element, attrs, ngModel) {
if (!ngModel) return;
scope.$watch(function() {
return ngModel.$modelValue
},
function() {
validate();
});
var validate = function() {
scope.array = JSON.parse(scope.array);
var elem_value = element.val();
var obj = scope.array.find(function(value, i) {
return value == elem_value && scope.index != i;
});
ngModel.$setValidity('duplicate', obj ? false : true);
};
}
}
});
&#13;
<!DOCTYPE html>
<html ng-app="app">
<head>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.5.7/angular.min.js"></script>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.6/css/bootstrap.min.css" />
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.2.4/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.6/js/bootstrap.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular-messages/1.5.7/angular-messages.min.js"></script>
</head>
<body ng-controller="mainCtrl">
<div class="col-sm-6">
<ul style="list-style-type: none;-webkit-padding-start: 0px;margin-bottom:0px">
<li ng-repeat="ip in site.ips track by $index" style="margin-bottom:0px">
<ng-form name="ipForm">
<div class="input-group" style="margin-top:5px" ng-class="{ 'has-error' : ipForm.ip_address.$invalid }">
<input type="text" name="ip_address" class="form-control input-sm" ng-pattern='/^([0-9]{1,3})[.]([0-9]{1,3})[.]([0-9]{1,3})[.]([0-9]{1,3})$/' style="display: inline;" ng-model="site.ips[$index]" placeholder="{{translate('config.sites.msg.site.ip.adress')}}"
required duplicate index="{{$index}}" array="{{site.ips}}" />
<div class="input-group-addon">
<i class="glyphicon glyphicon-remove-circle" ng-click="removeIp(site, ip, $index)"></i>
</div>
<div class="help-block" ng-messages="ipForm.ip_address.$error" ng-if="ipForm.ip_address.$touched">
<p ng-message="required">This field is required</p>
<p ng-message="minlength">This field is too short</p>
<p ng-message="maxlength">This field is too long</p>
<p ng-message="pattern">This needs to be a valid ip</p>
<p ng-message="duplicate">Duplicate!</p>
</div>
</div>
</ng-form>
</li>
</ul>
</div>
</body>
</html>
&#13;
注意:它只是指向正确的方向,也许它不是最有效的方法。
无论如何,我希望它有所帮助。