假设,我想对文本输入应用屏蔽函数。它可以对输入的电话号码进行适当的风格化(例如,对于输入5553334444
,它将输出(555) 333-4444
),也可以只是简单地将输入控件中的值大写。
我知道的方法使用ngModel
控制器(通过require: "ngModel"
),并在$parser
函数中设置新的大写$viewValue
:
ngModel.$parsers.unshift(function(val){
var uppercase = val && val.toUpperCase();
if (uppercase !== val){
ngModel.$setViewValue(uppercase);
ngModel.$render();
}
return uppercase;
});
但现在,假设我想使用ng-model-options="{debounce: 400}"
,因为我不想太快地触发模型的变化:
<input ng-model="foo" ng-model-options="{debounce: 400}"
ng-change="doBackendQuery(foo)"
uppercase>
在上面的例子中,我不想太快地触发doBackendQuery
,因为它会进行HTTP调用。debounce
可以防止这种情况发生,但它也可以防止uppercase
指令立即执行,从而导致用户看到小写文本。
Q:如何编写uppercase
指令来立即更改$viewValue
,而无需等待debounce
?
(注意:我不想对底层DOM元素进行假设——这与DOM不可知的ng-model
的想法背道而驰)
plunker
一个破解的解决方案(未经测试):
<input ng-model="foo" ng-model-options="{debounce: 400}"
ng-change="doBackendQuery(foo)"
uppercase style="text-transform: uppercase;">
您还可以更改uppercase
指令以自动设置该样式,或者使用css:
input[uppercase] {
text-transform: uppercase;
}
这对我有效:
app.directive('capitalize', function() {
return {
restrict: 'A',
require: 'ngModel',
link: function(scope, element, attrs, modelCtrl) {
element.on('input', function() {
var capitalized = element.val().toUpperCase();
element.val(capitalized);
modelCtrl.$setViewValue(capitalized);
});
modelCtrl.$parsers.push(function(value) {
return value.toUpperCase();
});
}
};
});
(function(){
angular
.module('example', [])
.directive('uppercase', [function(){
return {
restrict: 'A',
require: 'ngModel',
link: function(scope, iElem, iAttrs, ngModel){
iElem.on('input', function(){
var elem = angular.element(this),
valOrigin = elem.val();
val = toUpperCase(valOrigin);
elem.val( val );
ngModel.$viewValue = toLowerCase(valOrigin);
});
ngModel.$parsers.push(function(value){
value = toLowerCase(value);
return value;
});
ngModel.$formatters.push(function(value){
value = toUpperCase(value);
return value;
});
function toLowerCase(value){
return (value + '').toLowerCase();
}
function toUpperCase(value){
return (value + '').toUpperCase();
}
}
}
}])
.controller('ExampleController', [function() {
var vc = this;
vc.user = {
name: 'let' start!'
};
}]);
angular
.bootstrap(document, ['example']);
})();
<script src="https://code.angularjs.org/1.4.7/angular.min.js"></script>
<div ng-controller="ExampleController as example">
<form name="userForm">
<label>Name:
<input type="text" name="userName" uppercase ng-model="example.user.name" ng-model-options="{debounce: 500}" />
</label>
<p>Name: <span>{{ example.user.name }}</span></p>
</form>
</div>