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。所有错误消息一起出现,这不是预期的行为。
请帮助我。以下是demo plunker的问题。
(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>
答案 0 :(得分:0)
我找到了解决方案,因为我错过了对ng-required的理解,如果输入框中有一些值(是否为0),那么满足ng-required就是为什么要解决问题。
通过在条件输入框上使用watch获得解决方案。下面是相关代码,(这里我使用json值作为$ watch,如果数组发生变化则不调用,所以改成json数据)
var
它也可以在没有$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);
}
});
的情况下实现,只需添加一个操作车辆总数的方法,然后将其作为表单提交按钮启用/禁用的标志重新添加。
$watch
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;
}
};
答案 1 :(得分:-1)
我对你的掠夺者做了一些改变,认为所有的问题都是固定的,因为我理解你的观点。这是链接 - https://plnkr.co/edit/bDzuBa?p=preview
choose [
GET >=> pathScan "/instrument/%d" getResourceById
GET >=> pathScan "/instrument/%d/prices" getPricesById
]