多应用+插件架构,代码干净,二开方便,首家独创一键云编译技术,文档视频完善,免费商用码云13.8K 广告
如何限制Input框只能输入数字? 在Input里使用自定义指令 ~~~ <input type="text" ng-model="num" fdc-filter> ~~~ 然后在自定义指令的link标签绑定element ,使用正则,只匹配数字 当keyup时,把输入的不是数字的用空字符串替换掉: ~~~ link: function(scope,element){ var regex = /\D/g; element.on('keyup',function(){ this.value = this.value.replace(regex,''); }); } ~~~ 结果发现,我们输入字母时,会出现闪一下然后消失的情况 ![](https://box.kancloud.cn/f1b0bc534afbc5af1571858144a36b01_265x80.png) 然后消失: ![](https://box.kancloud.cn/1937cd0bfc58c9abbbb534d4e5e61a59_258x67.png) 原因是,我们按下按钮时ui线程已经渲染了页面,然后再执行了keyup事件,然后再替换掉,就会出现这种情况 然后换了一个事件:keydown 结果发现: ***** 如何把input text 限制只能输入数字呢? 首先我们在Input里加入自定义指令; ~~~ <input type="text" class="form-control" ng-model="vm.searchParams.id" number-filter> ~~~ 在number-filter指令里,我们使用require require表示需要依赖的指令;如果有依赖的指令,那么link的第四个参数也就是依赖指令的对外暴露的controller也自动会被注入进来 由于ng-model也是一个指令,所以我们可以把ng-model依赖注入到我们自己的自定义指令中: ~~~ .directive('numberFilter',[function () { return{ restrict:'AE', require:'ngModel', link:function (scope,element,attrs,ctrl) { } } }]); ~~~ 此时,link就有了第4个参数,第4个参数是用来把指令对外暴露的controller注入进来,因为我们使用的事ng-model,所以,这第4个参数就是ng-model的controller,注意,并不是当前页面的controller,因为ng-model也是一个angular封装好的自定义指令,它在内部有自己的controller,这个注入的controller是ng-model内部的controller, 然后这个controller有几个方法:我们需要用到的是: $parsers: ![](https://box.kancloud.cn/99a99bce956523839ba5e4e7c496b787_516x180.png) 就是说我们在input输入值,然后会经过这个$parsers,最后传到angular 的model层中, $setViewValue: $setViewValue用于设置视图值(上面的例子就是将input的value值赋值给$viewValue) 这个用来设置视图值,改变这里的值会直接反应到我们的视图上,是我们能看到的值 $render:$render函数负责将模型值同步到视图上, 如果模型值被改变,需要同步视图的值。 好了,知道这几个东西可以知道该怎么写了: 首先我们在自定义指令中使用$parsers的方法 把我们从dom获取的值进行转换, 如果不是数字,我们把他转换为空,然后angular,执行$parsers之后就会把转换后的值加入model层中; ~~~ .directive('numberFilter',[function () { return{ restrict:'AE', require:'ngModel', link:function (scope,element,attrs,ctrl) { ctrl.$parsers.push(function(text){ var reg = /[^\d]/g, newText = text.replace(reg,'') }) } } }]); ~~~ 这里上面的text指的是我们input输入的值,然后return就是输出的值,就是输出到model层的值; 然后我们使用正则把不是数字的变为空,这里的[^]表示逻辑非,\d,表示数字,意思//g就是全局匹配,整体意思是匹配出不是数字的,然后使用''空字符串代替掉, 然后我们需要把这个newText,return出去,此时model层里的值就会变成newText 但是,此时视图层还没有进行改变,所以我们要使用$setViewValue,立即更新视图层,还有$render同步, ~~~ .directive('numberFilter',[function () { return{ restrict:'AE', require:'ngModel', link:function (scope,element,attrs,ctrl) { ctrl.$parsers.push(function(text){ var reg = /[^\d]/g, newText = text.replace(reg,''); if(newText!== text){ ctrl.$setViewValue(outPut); ctrl.$render(); } return newText }) } } }]); ~~~ 最后把里面的函数抽取到外面去,在里面调用,就变成 ~~~ .directive('numberFilter',[function () { return{ restrict:'AE', require:'ngModel', link:function (scope,element,attrs,ctrl) { function formUser(text) { var reg = /[^\d]/g, outPut = text.replace(reg,''); if(outPut!== text){ ctrl.$setViewValue(outPut); ctrl.$render(); } return outPut } ctrl.$parsers.push(formUser) } } }]); ~~~