条件 ng 需要集体检查 3 个输入框不起作用



Angular v 1.6.8

我有一个带有 3 个输入框的表单,用户在其中输入数字,我的要求是其中一个输入框必须至少具有一些值(大于 0(,但这不起作用。

我为所有 3 个输入框绑定了一个带有ng-required的方法,此方法检查所有 3 个计算结果为true/false的输入框值。在这种方法中,我使用本机javascript方法.some((来检查任何一个输入框的值是否大于0,而不是不需要输入框的其余部分(即ng-required评估为false(

我还添加了一个指令,用于控制输入框的最大值和最小值。

现在我的问题是

1.当用户为所有3个输入框输入0时,表单变得有效,这是不正确的。(这是我的主要问题(
2。如果我在输入框中输入的超过最大值,则指令会正确给出验证错误,但是$parse键也($error": { "validRange": true, "parse": true })(?为什么会这样?

3.所有错误消息一起出现,这不是预期的行为。

请帮助我。这是带有该问题的演示器。

(function() {
'use strict';
angular
.module('app', [])
.controller('AppController', function($scope) {
var vm = this;
angular.extend(vm, {
formdata: {
username: "",
vehicles: {
bike: null,
car: null,
cycle: null
}
}
});
vm.isOptionsRequired = function(item) {
// console.log("isOptionsRequired", item);
var arr = Object.values(item);
console.log("arr", arr);
var final = arr.some(function(option) {
return option > 0;
});
// console.log("final", final);
return !final;
};
vm.updateForm = function() {
console.log('updateForm called', vm.formdata);
}
}).directive('validateNumber', function($timeout) {
return {
restrict: 'A',
require: 'ngModel',
scope: {
validateNumber: '='
},
link: function(scope, element, attr, ngModel) {
function checkOut(text) {
if (text < scope.validateNumber.min || text > scope.validateNumber.max) {
console.info("if inside directive");
ngModel.$setValidity('validRange', false);
} else {
console.info("else inside directive");
ngModel.$setValidity('validRange', true);
if (text) {
var transformedInput = text.replace(/[^0-9]/g, '');
if (transformedInput !== text) {
ngModel.$setValidity('validNumber', false);
angular.element(element).css({
'background-color': '#ffc7c7'
});
ngModel.$setViewValue(transformedInput);
ngModel.$render();
} else {
$timeout(function() {
angular.element(element).css({
'background-color': '#ffffff',
'transition': 'background-color 40ms ease-out',
'-ms-transition': 'background-color 40ms linear',
'-webkit-transition': 'background-color 40ms linear'
});
}, 100);
ngModel.$setValidity('validNumber', true);
}
return transformedInput;
}
return undefined;
}
}
ngModel.$parsers.unshift(checkOut);
}
};
});
})();
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>
<link href="https://netdna.bootstrapcdn.com/bootstrap/3.0.0/css/bootstrap.min.css" rel="stylesheet" />
<script src="https://netdna.bootstrapcdn.com/bootstrap/3.3.4/js/bootstrap.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.0/angular.js"></script>
<script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.3.16/angular-messages.min.js"></script>
<!DOCTYPE html>
<html ng-app="app">
<body class="container" ng-controller="AppController as vm">
<h1>Hello Plunker!</h1>
<form class="form-horizontal" name="wheelForm" novalidate="">
<div class="row">
<div class="form-group">
<label class="col-md-4 control-label">Name</label>
<div class="col-md-8" ng-class="{ 'has-error': wheelForm.username.$touched && wheelForm.username.$invalid }">
<input type="text" name="username" class="form-control" ng-model="vm.formdata.username" required="" />
<div ng-if="wheelForm.username.$touched && wheelForm.username.$invalid" ng-messages="wheelForm.username.$error" class="has-error">
<span ng-message="required">Please enter name.</span>
</div>
</div>
</div>
<div class="form-group ">
<label class="col-md-4"># of Bikes</label>{{wheelForm.vehicle_bike | json }}
<div class="col-md-8" ng-class="{ 'has-error': wheelForm.vehicle_bike.$touched && wheelForm.vehicle_bike.$invalid }">
<input type="text" placeholder="Enter 0 for no vehicles" name="vehicle_bike" class="form-control" ng-model="vm.formdata.vehicles.bike" ng-required="vm.isOptionsRequired(vm.formdata.vehicles)" validate-number="{min:0, max:10}" />
<div ng-messages="wheelForm.vehicle_bike.$error" ng-if="wheelForm.vehicle_bike.$touched && wheelForm.vehicle_bike.$invalid" class="text-danger">
<!-- <span ng-message="parse">Enter 0 if no bike servlet required</span> -->
<span ng-message="validRange">Number must be between 0 and 10.</span>
<span ng-message="required">Please enter Number.</span>
</div>
</div>
</div>
<div class="form-group ">
<label class="col-md-4"># of Cars</label>{{wheelForm.vehicle_car | json }}
<div class="col-md-8" ng-class="{ 'has-error': wheelForm.vehicle_car.$touched && wheelForm.vehicle_car.$invalid }">
<input type="text" placeholder="Enter 0 for no vehicles" name="vehicle_car" class="form-control" ng-model="vm.formdata.vehicles.car" ng-required="vm.isOptionsRequired(vm.formdata.vehicles)" validate-number="{min:0, max:10}" />
<div ng-messages="wheelForm.vehicle_car.$error" ng-if="wheelForm.vehicle_car.$touched && wheelForm.vehicle_car.$invalid" class="text-danger">
<span ng-message="validRange">Number must be between 0 and 10.</span>
<span ng-message="required">Please enter Number.</span>
</div>
</div>
</div>
<div class="form-group ">
<label class="col-md-4"># of Cycles</label>{{wheelForm.vehicle_cycle | json }}
<div class="col-md-8" ng-class="{ 'has-error': wheelForm.vehicle_cycle.$touched && wheelForm.vehicle_cycle.$invalid }">
<input type="text" placeholder="Enter 0 for no vehicles" name="vehicle_cycle" class="form-control" ng-model="vm.formdata.vehicles.cycle" ng-required="vm.isOptionsRequired(vm.formdata.vehicles)" validate-number="{min:0, max:10}" />
<div ng-messages="wheelForm.vehicle_cycle.$error" ng-if="wheelForm.vehicle_cycle.$touched && wheelForm.vehicle_cycle.$invalid" class="text-danger">
<span ng-message="validRange">Number must be between 0 and 10.</span>
<span ng-message="required">Please enter Number.</span>
</div>
</div>
</div>
<div class="form-actions m-t-lg text-center">
<button ng-disabled="wheelForm.$invalid" class="btn btn-block btn-success" ng-click="vm.updateForm()">
Update
</button>
</div>
</div>
</form>
</body>
</html>

我找到了解决方案,因为我错过了对 ng-required 的理解,如果输入框中有一些值(无论是 0 (而不是满足 ng-required 这就是遇到问题的原因。

通过在条件输入框上使用监视来获得解决方案。 下面是相关代码,(这里我使用 json 值$watch因为如果数组发生变化,请不要调用,因此更改为 JSON 数据(

$scope.$watch(function() {
console.log('inside watch');
return angular.toJson(vm.formdata.vehicles);
}, function(nv, ov) {
console.log(nv, ov);
if (nv !== ov) {
var arr = Object.values(angular.fromJson(nv)); // change json > array
var arrVehicles = arr.map(Number); // change all array element from string to integer
console.log("vehicle Array:", arrVehicles);
var sum = arrVehicles.reduce(function(sum, cur) {
// console.log(sum, cur);
return sum + cur;
}, 0);
console.log("Boolean(sum)", Boolean(sum));
$timeout(function() {
$scope.wheelForm.$setValidity("enough", Boolean(sum));
if( !Boolean(sum)) {
vm.invalidRequest = true;
vm.errorMessage = "At least 1 vehicle is required for the registration.";
} else {
vm.invalidRequest = false;
vm.errorMessage = "";
}
}, 0);
} else {
$scope.wheelForm.$setValidity("enough", false);
}
});

这是更新的 plunker


替代方法

无需$watch即可实现 此外,只需添加一种操作车辆总数并将其重新调整添加为表单提交按钮启用/禁用的标志的方法。

.JS

vm.isEnoughVehicles = function(vehicles) {
if (angular.isDefined(vehicles)) {
var arrVehicles = Object.values(vehicles).map(Number); // change array value from string to integer
var total = arrVehicles.reduce(function(sum, prev) {
var cur = isNaN(prev) ? 0 : prev;
return sum + cur;
}, 0);
return (total > 0 ? true : false);
} else {
return false;
}
};

.HTML

<button ng-disabled="wheelForm.$invalid || !vm.isEnoughVehicles(vm.formdata.vehicles)" class="btn btn-block btn-success" ng-click="vm.updateForm()">
Update
</button>

更新普伦克

我在您的 plunker 中进行了一些更改,并认为所有问题都已解决,因为我理解了您的观点。这是链接 - https://plnkr.co/edit/bDzuBa?p=preview

<!DOCTYPE html>
<html ng-app="app">
<head>
<script data-require="jquery@3.1.1" data-semver="3.1.1" src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>
<link data-require="bootstrap@3.3.0" data-semver="3.3.0" rel="stylesheet" href="https://netdna.bootstrapcdn.com/bootstrap/3.0.0/css/bootstrap.min.css" />
<script data-require="bootstrap@3.3.0" data-semver="3.3.0" src="https://netdna.bootstrapcdn.com/bootstrap/3.3.4/js/bootstrap.min.js"></script>
<script data-require="angular.js@1.6.0" data-semver="1.6.0" src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.0/angular.js"></script>
<script data-require="ng-messages@1.3.16" data-semver="1.3.16" src="http://ajax.googleapis.com/ajax/libs/angularjs/1.3.16/angular-messages.min.js"></script>
<script src="script.js"></script>
<script src="directive.js"></script>
</head>
<body class="container" ng-controller="AppController as vm">
<h1>Hello Plunker!</h1>
<form class="form-horizontal" name="wheelForm" novalidate="">
<div class="row">
<div class="form-group">
<label class="col-md-4 control-label">Name</label>
<div class="col-md-8" ng-class="{ 'has-error': wheelForm.username.$touched && wheelForm.username.$invalid }">
<input type="text" name="username" class="form-control" ng-model="vm.formdata.username" required="" />
<div ng-if="wheelForm.username.$touched && wheelForm.username.$invalid" ng-messages="wheelForm.username.$error" class="has-error">
<span ng-message="required">Please enter name.</span>
</div>
</div>
</div>
<div class="form-group ">
<!--<label class="col-md-4"># of Bikes</label>{{wheelForm.vehicle_bike | json }}-->
<div class="col-md-8" ng-class="{ 'has-error': wheelForm.vehicle_bike.$touched && wheelForm.vehicle_bike.$invalid }">
<input type="text" placeholder="Enter 0 for no vehicles" name="vehicle_bike" class="form-control" ng-model="vm.formdata.vehicles.bike" validate-number="{min:1, max:16}" ng-required="true"  />
<div ng-messages="wheelForm.vehicle_bike.$error" ng-if="wheelForm.vehicle_bike.$touched && wheelForm.vehicle_bike.$invalid" class="text-danger">
<!-- <span ng-message="parse">Enter 0 if no bike servlet required</span> -->
<span ng-message="validRange">Number must be between 0 and 16.</span>
<span ng-message="validNumber">Please enter valid Number.</span>
</div>
</div>
</div>
<div class="form-group ">
<!--<label class="col-md-4"># of Cars</label>{{wheelForm.vehicle_car | json }}-->
<div class="col-md-8" ng-class="{ 'has-error': wheelForm.vehicle_car.$touched && wheelForm.vehicle_car.$invalid }">
<input type="text" placeholder="Enter 0 for no vehicles" name="vehicle_car" class="form-control" ng-model="vm.formdata.vehicles.car" ng-required="true" validate-number="{min:1, max:16}" required />
<div ng-messages="wheelForm.vehicle_car.$error" ng-if="wheelForm.vehicle_car.$touched && wheelForm.vehicle_car.$invalid" class="text-danger">
<span ng-message="validRange">Number must be between 0 and 16.</span>
<span ng-message="validNumber">Please enter valid Number.</span>
</div>
</div>
</div>
<div class="form-group ">
<!--<label class="col-md-4"># of Cycles</label>{{wheelForm.vehicle_cycle | json }}-->
<div class="col-md-8" ng-class="{ 'has-error': wheelForm.vehicle_cycle.$touched && wheelForm.vehicle_cycle.$invalid }">
<input type="text" placeholder="Enter 0 for no vehicles" min="1" name="vehicle_cycle" class="form-control" ng-model="vm.formdata.vehicles.cycle" ng-required="true" validate-number="{min:1, max:16}" required />
<div ng-messages="wheelForm.vehicle_cycle.$error" ng-if="wheelForm.vehicle_cycle.$touched && wheelForm.vehicle_cycle.$invalid" class="text-danger">
<span ng-message="validRange">Number must be between 0 and 16.</span>
<span ng-message="validNumber">Please enter valid Number.</span>
</div>
</div>
</div>
<div class="form-actions m-t-lg text-center">
<button ng-disabled="wheelForm.$invalid" class="btn btn-block btn-success" ng-click="vm.updateForm()">
Update
</button>
</div>
</div>
</form>
</body>
</html>

最新更新