如何用AngularJs选中所有input元素并全局实现输入转大写
如何在AngularJS全局实现输入框自动转大写?
嘿,我懂你之前用jQuery实现全局输入框转大写那叫一个顺手,现在换到AngularJS的多控制器单页应用,想实现同样的全局功能却有点摸不着头脑对吧?毕竟Angular不提倡直接操作DOM,和jQuery的思路不太一样。不过别担心,有两种靠谱的方法能帮你搞定,而且都能在所有控制器里生效!
推荐方案:用自定义指令实现(Angular最佳实践)
Angular的核心思想是数据驱动视图,直接操作DOM不是最优解,自定义指令才是处理这类DOM交互的正确姿势。而且指令可以轻松实现全局生效,还能保证数据和视图同步。
方法1:可手动启用的全局指令
先写一个属性指令,你可以选择性地给需要转大写的input加上这个属性:
angular.module('你的应用模块名') .directive('uppercaseInput', function() { return { restrict: 'A', // 作为属性使用 require: 'ngModel', // 依赖ngModel控制器来处理数据绑定 link: function(scope, element, attrs, ngModelCtrl) { // 当用户输入内容时,把值转成大写 ngModelCtrl.$parsers.push(function(value) { var uppercaseValue = value ? value.toUpperCase() : value; // 更新视图,避免输入时先显示小写再跳大写的闪烁问题 ngModelCtrl.$setViewValue(uppercaseValue); ngModelCtrl.$render(); return uppercaseValue; }); // 初始化时如果input有默认值,也转成大写 if (ngModelCtrl.$viewValue) { var uppercaseInitValue = ngModelCtrl.$viewValue.toUpperCase(); ngModelCtrl.$setViewValue(uppercaseInitValue); ngModelCtrl.$render(); } } }; });
使用的时候,只需要在input上加上uppercase-input属性即可:
<input type="text" ng-model="formData.username" uppercase-input>
方法2:自动全局生效的指令
如果想让所有带ngModel的input都自动转大写,不需要手动加属性,可以直接写一个匹配input元素的指令:
angular.module('你的应用模块名') .directive('input', function() { return { restrict: 'E', // 匹配所有<input>元素 require: 'ngModel', // 只对有ngModel的input生效 link: function(scope, element, attrs, ngModelCtrl) { // 转换逻辑和上面一致 ngModelCtrl.$parsers.push(function(value) { var uppercaseValue = value ? value.toUpperCase() : value; ngModelCtrl.$setViewValue(uppercaseValue); ngModelCtrl.$render(); return uppercaseValue; }); // 初始化默认值转大写 if (ngModelCtrl.$viewValue) { var uppercaseInitValue = ngModelCtrl.$viewValue.toUpperCase(); ngModelCtrl.$setViewValue(uppercaseInitValue); ngModelCtrl.$render(); } } }; });
这样一来,项目里所有绑定了ngModel的input都会自动把输入内容转成大写,不管当前用的是哪个控制器,完美符合你的需求!
备选方案:优化你原本的run阶段代码(不推荐,但符合你的习惯)
如果你习惯了之前在run里写jQuery风格的代码,也可以调整一下,让它适配Angular的消化循环,避免数据和视图不同步的问题:
angular.module('你的应用模块名') .run(function($timeout) { // 用$timeout确保DOM已经完全渲染,才能找到所有input元素 $timeout(function() { angular.element('input').on('keyup', function() { var uppercaseVal = this.value.toUpperCase(); if (this.value !== uppercaseVal) { this.value = uppercaseVal; // 必须触发input事件,让Angular的ngModel感知到值的变化 angular.element(this).triggerHandler('input'); } }); }); });
这里要注意两点:
- 必须用
$timeout把代码放到下一个消化循环,不然run阶段DOM还没渲染完,找不到input元素。 - 修改value后要触发
input事件,不然Angular的ngModel不会更新,导致数据和视图不一致。
不过还是更推荐用指令的方式,毕竟这是Angular的设计初衷,代码也更易维护和扩展。
内容的提问来源于stack exchange,提问作者may mijangos
相关产品推荐
相关产品推荐

