已经存在许多问题,讨论能够根据另一个模型更改的值验证一个字段。其中许多问题似乎都已过时,因为Angular在这些问题发生后发生了变化。
我有一个指令允许用户选择"颜色"。还有其他指令允许用户选择"尺寸" (宽度和高度)。某些颜色仅适用于某些尺寸。
我的颜色"指令有一个额外的指令来管理验证。如果宽度和高度超过一定数量,我添加我的错误信息,一切都很好。
然而,当"尺寸"时,同样的验证不会触发。更改。我试图在大小字段上使用on-change="form.myfield.$validate()
,这提供了所需的功能,但是因为该字段变为无效,"颜色" model现在是undefined
。
当另一个模型的值发生变化时,是否有一种简单的方法可以在字段上触发验证?
这是一个Plunkr。
http://plnkr.co/edit/DQhRFcIKkLlf0NfnuDJa?p=preview
修改
我越是想到这一点,我越相信我意识到由于各种多元素指令之间发生的复杂交互,对这种类型的应用程序的验证将非常困难。我认为根据某些模型值设置各种输入的可接受值可能更简单,从而防止首先选择任何无效值。
答案 0 :(得分:3)
您可以在width
和height
属性上添加监视并有条件地设置颜色输入的有效性。
var app = angular.module('plunker', []);
app.controller('MainCtrl', function($scope) {
$scope.colors = [
{
description: 'Red',
sku: '5555',
oversize: true
},
{
description: 'Blue',
sku: '6666',
oversize: false
}
]
});
app.directive('oversize', function(){
return {
require: 'ngModel',
link: function(scope, elem, attrs, ctrl) {
function validator (modelVal, viewVal) {
var w = scope.width;
var h = scope.height;
var isValid = false;
if (w > 4 && h > 4) {
if (modelVal.oversize === true) {
isValid = true;
}
} else {
isValid = true;
}
return isValid;
}
ctrl.$validators.oversize = validator;
scope.$watch('width', function () {
ctrl.$setValidity("oversize", validator(scope.color));
})
scope.$watch('height', function () {
ctrl.$setValidity("oversize", validator(scope.color));
})
}
}
})

<!DOCTYPE html>
<html ng-app="plunker">
<head>
<meta charset="utf-8" />
<title>AngularJS Plunker</title>
<script>document.write('<base href="' + document.location + '" />');</script>
<link rel="stylesheet" href="style.css" />
<script data-require="angular.js@1.3.x" src="https://code.angularjs.org/1.3.16/angular.js" data-semver="1.3.16"></script>
<script src="app.js"></script>
</head>
<body ng-controller="MainCtrl">
<form action="" name="form">
<p>Red is available in oversize, blue is not.</p>
<p>If both width and height are > 4, blue cannot be used</p>
<div ng-show="form.color.$error.oversize">That is not available in this size</div>
Color
<select oversize name="color" ng-model="$parent.color" ng-options="c.description for c in colors track by c.sku"></select>
<br>
Width
<select name="width" ng-model="width" ng-options="v for v in [1,2,3,4,5]"></select>
<br>
Height
<select name="height" ng-model="height" ng-options="v for v in [1,2,3,4,5]" id=""></select>
</form>
<p>Oversize for {{color.description}} is {{color.oversize}}</p>
</body>
</html>
&#13;
答案 1 :(得分:1)
这不应该是一个单独的答案,因为99%的答案来自ShankarSangoli的答案,它可能不再与OP相关,但希望这将有助于其他人。未定义颜色模型的值的问题是由验证引起的。如果验证失败,Angular Validations会将模型设置为undefined(请参阅$ validate部分)。如果使用ng-model-options="{ allowInvalid: true }"
装饰颜色的选择标记,则验证将允许将值保存到模型中。这里的一个重要问题是它将保存到您的模型中,任何提交操作都将使用此无效数据。当存在任何验证错误时,请小心限制页面提交,并且你应该都很好。
同样,这不应该是一个单独的答案,但我没有足够的代表发表评论。 ShankarSangoli的回答应该得到大部分的信用。如果没有它,我将无法做到这一点。
var app = angular.module('plunker', []);
app.controller('MainCtrl', function($scope) {
$scope.colors = [
{
description: 'Red',
sku: '5555',
oversize: true
},
{
description: 'Blue',
sku: '6666',
oversize: false
}
]
});
app.directive('oversize', function(){
return {
require: 'ngModel',
link: function(scope, elem, attrs, ctrl) {
function validator (modelVal, viewVal) {
var w = scope.width;
var h = scope.height;
var isValid = false;
if (w > 4 && h > 4) {
if (modelVal.oversize === true) {
isValid = true;
}
} else {
isValid = true;
}
return isValid;
}
ctrl.$validators.oversize = validator;
scope.$watch('width', function () {
ctrl.$setValidity("oversize", validator(scope.color));
})
scope.$watch('height', function () {
ctrl.$setValidity("oversize", validator(scope.color));
})
}
}
})
&#13;
<!DOCTYPE html>
<html ng-app="plunker">
<head>
<meta charset="utf-8" />
<title>AngularJS Plunker</title>
<script>document.write('<base href="' + document.location + '" />');</script>
<link rel="stylesheet" href="style.css" />
<script data-require="angular.js@1.3.x" src="https://code.angularjs.org/1.3.16/angular.js" data-semver="1.3.16"></script>
<script src="app.js"></script>
</head>
<body ng-controller="MainCtrl">
<form action="" name="form">
<p>Red is available in oversize, blue is not.</p>
<p>If both width and height are > 4, blue cannot be used</p>
<div ng-show="form.color.$error.oversize">That is not available in this size</div>
Color
<select oversize name="color" ng-model="$parent.color" ng-options="c.description for c in colors track by c.sku" ng-model-options="{ allowInvalid: true }" ></select>
<br>
Width
<select name="width" ng-model="width" ng-options="v for v in [1,2,3,4,5]" ></select>
<br>
Height
<select name="height" ng-model="height" ng-options="v for v in [1,2,3,4,5]" ></select>
</form>
<p>Oversize for {{color.description}} is {{color.oversize}}</p>
</body>
</html>
&#13;