可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
I have markup like this:
<form name="myForm" ng-controller="myCtrl" novalidate>
<input ng-model="theValue" type="range" min="0" max="100" required>
<input ng-model="theValue" type="number" required></input>
<span ng-show="theValue.$error.number">Hey! No letters, buddy!</span>
</form>
And I want the span to show when the user accidentally types a letter in the second input. Simple, right? As an (probably) related problem, the value in the second input disappears when the user moves the first slider input. Why? This doesn't happen if I remove type-number
from the markup.
To be clear: I want the user to see the tooltip error immediately when it's typed, without any "submit" action. (I'd prefer not to have to use the form
element at all in fact, but all the related demos seem to require it.)
http://jsfiddle.net/7FfWT/
Any workaround is most welcome. Please post a working fiddle if possible.
回答1:
There seems to be a weird issue with type="number"
playing nicely with other inputs
.
The posts in this google groups post should get you on the right track. In particularly, the last post there: https://groups.google.com/forum/#!msg/angular/Ecjx2fo8Qvk/x6iNlZrO_mwJ
The jsfiddle link is: http://jsfiddle.net/ABE8U/
As a work around, he's made a directive:
.directive('toNumber', function () {
return {
require: 'ngModel',
link: function (scope, elem, attrs, ctrl) {
ctrl.$parsers.push(function (value) {
return parseFloat(value || '');
});
}
};
});
Credit to Schmuli Raskin
回答2:
Also you can use ng-pattern as validator:
<input type="number" ng-model="theValue" name="theValue" step="1" min="0" max="10" ng-pattern="integerval" required>
<span ng-show="form.theValue.$invalid">Hey! No letters, buddy!</span>
$scope.integerval = /^\d*$/;
回答3:
I've updated the directive to work with ng-repeat filters. Notice the '$', which is a wildcard. This directive should handle 0 just fine. It fails over to wildcard on
.directive('toNumber', function() {
return {
require: 'ngModel',
link: function(scope, elem, attrs, ctrl) {
ctrl.$parsers.push(function(value) {
return value===0 ? 0 : (parseFloat(value) || '$');
});
};
})
回答4:
jzm's answer worked for me until I needed '0' as an input. I adjusted jzm's code:
.directive('toNumber', function () {
return {
require: 'ngModel',
link: function (scope, elem, attrs, ctrl) {
ctrl.$parsers.push(function (value) {
if (value === 0)
return 0;
return parseFloat(value || '');
});
}
};
});
Notice the addition of the if (value === 0)
block.
Someone who understands JavaScript logical comparisons better than I could probably create more elegant code.
回答5:
jzm,s answer is really wonderful trick and saved my time.
I am just taking it to one step further and replacing parseFloat(value)
with what it actually does.
directive('number', function () {
return {
require: 'ngModel',
link: function (scope, elem, attrs, ngModel) {
ngModel.$parsers.push(function (value) {
if (value==null)
return NaN;
});
}
};
});