由浅入深剖析Angular表单验证(2)

<form novalidate="novalidate"> <input type="text" ng-model="name" upper-case> </form> .directive("upperCase",function(){ return { restrict:"A", require:"ngModel", link:function($scope,$element,$attrs,$ngModel){ $ngModel.$parsers.push(function(value){ var viewValue; if(angular.isUndefined(value)){ viewValue = ""; }else{ viewValue = "" + value; } viewValue = viewValue[0].toUpperCase() + viewValue.substring(1); //设置界面内容 $ngModel.$setViewValue(viewValue); //渲染到界面上,这个函数很重要 $ngModel.$render(); return value; }) } } });

这里我们使用了$setViewValue和$render,$setViewValue设置viewValue为指定的值,$render把viewValue显示到界面上。

很多人以为使用了$setViewValue就能更新界面了,没有使用$render,最后不管怎么搞,界面都没刷新。

如果只使用了$ngModel.$parsers是不够的,$parsers只在用户在输入框输入新内容的时候触发,还有一种情况是需要重新刷新输入框的内容的:

那就是双向绑定,例如刚才的输入框绑定的是MainController中的$scope.name,当用户通过其他方式把$scope.name改成"hello",输入框中看不到首字母大写。

这时候就要使用$formatters,还是先看个例子吧.

<body ng-controller="MainController"> <form novalidate="novalidate"> <button ng-click="random()">随机</button> <input type="text" ng-model="name" upper-case> </form> </body>

MainController的内容:

angular.module("app", []) .controller("MainController", function ($scope, $timeout) { $scope.random = function(){ $scope.name = "hello" + Math.random(); } })

够简单吧,点击按钮的时候,$scope.name变成hello开头的随机内容.

很明显,hello的首字母没大写,不是我们想要的内容。

我们修改下指令的内容:

.directive("upperCase",function(){ return { restrict:"A", require:"ngModel", link:function($scope,$element,$attrs,$ngModel){ $ngModel.$parsers.push(function(value){ var viewValue = upperCaseFirstWord(handleEmptyValue(value)); //设置界面内容 $ngModel.$setViewValue(viewValue); //渲染到界面上,这个函数很重要 $ngModel.$render(); return value; }) //当过外部设置modelValue的时候,会自动调用$formatters里面函数 $ngModel.$formatters.push(function(value){ return upperCaseFirstWord(handleEmptyValue(value)); }) //防止undefined,把所有的内容转换成字符串 function handleEmptyValue(value){ return angular.isUndefined(value) ? "" : "" + value; } //首字母大写 function upperCaseFirstWord(value){ return value.length > 0 ? value[0].toUpperCase() + value.substring(1) : ""; } } } });

总结一下:

1.
-->用户在输入框输入内容

-->angular遍历$ngModel.$parsers里面的函数转换输入的内容,然后设置到$ngModel.$modelValue

-->在$ngModel.$parsers数组中的函数里,我们修改了$ngModel.$viewValue,然后$ngMode.$render()渲染内容。

2.

-->通过按钮生成随机的字符串设置到name

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/wzswxp.html