有三个输入域
<input type="text" name="foo1" ng-model="data.input1"/>
<ng-messages for="forms.myForm.foo1" role="alert">
<ng-message when="oneRequired"> Please set foo1 (or foo2 or foo3) </ng-message>
<ng-messages>
<input type="text" name="foo2" ng-model="data.input2"/>
<ng-messages for="forms.myForm.foo2" role="alert">
<ng-message when="oneRequired"> Please set foo2 (or foo1 or foo3) </ng-message>
<ng-messages>
<input type="text" name="foo3" ng-model="data.input3"/>
<ng-messages for="forms.myForm.foo3" role="alert">
<ng-message when="oneRequired"> Please set foo3 (or foo1 or foo2) </ng-message>
<ng-messages>我希望保证至少设置了一个输入字段的值。在这种情况下,不仅当前的验证字段$error应该计算为'false‘,而且所有其他字段也应该计算为’false‘。所有消息都应该消失。
我的第一个想法是使用一个指令和一个唯一的id将字段链接在一起:
<input type="text" name="foo1" ng-model="data.input1" one-required="i1_i2_i3_link_identifier/>也许我可以使用一个(单例)服务来注册控制器和当前值。但是我没有一个想法来确保所有链接的控制器(在指令中使用)在验证错误时都被更新。
发布于 2015-11-09 16:23:39
我强烈推荐使用https://github.com/turinggroup/angular-validator指令。它非常灵活,可以很容易地设置您的自定义验证器。通过这个指令,我可以去掉ng-message并大大清理我的html代码。
您可以在控制器或服务中设置一个自定义验证器,以便在整个站点中使用。
<input type = "text"
name = "firstName"
class = "form-control"
ng-model = "form.firstName"
validator = "myCustomValidator(form.firstName)"
validate-on="dirty"
required></div>这里有一个插入器和代码给你:http://plnkr.co/edit/X5XdYYekT4YZH6xVBftz?p=preview,正如你所看到的,这非常笨重,有很多代码。使用angular验证器,您可以将代码减少为内联在输入中,并添加一个控制器函数。
<form name="myForm">
<input type="text" name="foo1" ng-model="data.input1" required/>
<div ng-if="myForm.foo1.$error.required && myForm.foo2.$error.required && myForm.foo3.$error.required" class="error">
<ng-messages for="myForm.foo1" role="alert">
<ng-message="required"> Please set foo1 (or foo2 or foo3) </ng-message>
</ng-messages>
</div>
<br/>
<input type="text" name="foo2" ng-model="data.input2" required/>
<div ng-if="myForm.foo1.$error.required && myForm.foo2.$error.required && myForm.foo3.$error.required" class="error">
<ng-messages for="myForm.foo2" role="alert">
<ng-message="required"> Please set foo2 (or foo2 or foo3) </ng-message>
</ng-messages>
</div>
<br/>
<input type="text" name="foo3" ng-model="data.input3" required/>
<div ng-if="myForm.foo1.$error.required && myForm.foo2.$error.required && myForm.foo3.$error.required" class="error">
<ng-messages for="myForm.foo3" role="alert">
<ng-message="required"> Please set foo3 (or foo2 or foo3) </ng-message>
</ng-messages>
</div>
<br/>
</form> 发布于 2015-11-13 15:38:26
我使用一个保存这些值的中央服务和一个回调注册表解决了这个问题。当输入发生变化时,回调函数会一直被调用(使用监视器):
angular.module('myApp', []);
angular.module('myApp').controller('myFormController', function($scope) {
$scope.data = {
i1: "remove",
i2: "all",
i3: "values"
};
});
angular.module('myApp').factory('oneRequiredService', function() {
var service = {};
var container = {};
var observerCallbacks = {};
var isValid = function(groupId) {
var valid = false;
var modelStates = container[groupId];
angular.forEach(modelStates, function(modelValid) {
valid = valid || (modelValid ? true : false);
});
return valid;
};
var isRegistered = function(groupId) {
return container.hasOwnProperty(groupId);
};
var notifyAll = function(key) {
var valid = isValid(key);
if (isRegistered(key)) {
angular.forEach(observerCallbacks[key], function(callback, index) {
callback(valid);
});
};
};
service.register = function(groupId, scopeId, callback) {
this.updateValue(groupId, scopeId, undefined);
if (callback) {
this.registerCallback(groupId, callback);
}
};
service.registerCallback = function(groupId, callback) {
if (callback) {
observerCallbacks[groupId] = observerCallbacks[groupId] || [];
observerCallbacks[groupId].push(callback);
};
};
service.updateValue = function(groupId, scopeId, value) {
container[groupId] = container[groupId] || {};
container[groupId][scopeId] = value;
notifyAll(groupId);
};
return service;
});
angular.module('myApp').directive('oneRequired', function(oneRequiredService) {
return {
restrict: "A",
require: 'ngModel',
scope: true,
link: function(scope, element, attrs, ctrl) {
var modelAttr = attrs["ngModel"];
var linkIdentifier = attrs["oneRequired"];
var updateCurrentState = function(isValid) {
scope._valid = isValid;
};
scope.$watch(modelAttr, function(newVal, oldVal) {
oneRequiredService.updateValue(linkIdentifier, scope.$id, newVal);
});
scope.$watch('_valid', function(newVal, oldVal) {
ctrl.$setValidity('oneRequired', newVal);
});
oneRequiredService.register(linkIdentifier, scope.$id, updateCurrentState);
}
}
});<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.21/angular.min.js"></script>
<body ng-app="myApp">
<form ng-controller="myFormController" name="forms.myForm">
<label for="i_1">i_1</label>
<input id="i_1" name="i1" type="text" one-required="foo-bar" ng-model="data.i1" />
<span> i1-err-one-required: {{forms.myForm.i1.$error.oneRequired}} </span> <br>
<label for="i_2">i_2</label>
<input id="i_2" name="i2" type="text" one-required="foo-bar" ng-model="data.i2"/>
<span> i2 err-one-required: {{forms.myForm.i2.$error.oneRequired}} </span> <br>
<label for="i_3">i_3</label>
<input id="i_3" name="i3" type="text" one-required="foo-bar" ng-model="data.i3"/>
<span> i3-err-one-required: {{forms.myForm.i3.$error.oneRequired}} </span> <br>
</form>
</body>
https://stackoverflow.com/questions/33604720
复制相似问题