深入了解Angularjs指令中的ngModel
关于AngularJs的指令的知识学习,请参考。。。
这次我们接上次没讲完的知识继续。
前端人员在设计表单逻辑时,
在大部分情况下,我们需要为表单定义很多指令,
比如比较两个input内的值是否相同,是否不同等等,
这个时候我们就可以在angularJs定义指令的时候
使用require:‘ngModel’ 这个选项来增强我们对表单的操作,
这样就可以作为link选项的第四个参数,
link: function (scope,iElem,iAttr,ngmodel){ //其他逻辑代码 }
首先让我们在控制台输出ngmodel这个参数看看,代码如下
<!DOCTYPE html> <html lang="en" ng-app="app"> <head> <meta charset="UTF-8"> <title>Document</title> <script src="angular.js" charset="utf-8"></script> </head> <body ng-controller='ctrl'> <input type="text" test ng-model=_val> <script> var app = angular.module('app',[]); app.controller('ctrl',function ($scope){ $scope._val = "leifengshushu"; }) app.directive('test',function(){ return{ restrict: 'AE', require: 'ngModel', link: function (scope,iElem,iAttr,ngmodel){ console.log(ngmodel) } } }) </script> </body> </html>
可以看到这个对象包含很多属性和方法,
下面让我们一一讲解下
其中
1.
$viewValue为视图值,即显示在视图(页面)的实际值(就是上面例子中input输入框的值)
$modelValue为模型值,即赋给ng-model的值(与控制器绑定的值)
两者不一定相等,因为$viewValue同步到$modelValue要经过一系列的操作(经过三个管道)。
虽然大多数情况下两者是相等的(例如上面的例子)
2.
$parsers为一个执行它里面每一个元素(每一个元素都是一个函数)的数组,
主要是用来做验证和转换值的过程,
ngModel从DOM读取的值会被传入到其中的函数
它会依次执行每一个函数,把每一个函数执行的结果传个下一个函数,
而最后一个函数执行的值将会传到model中,
我们可以将函数push进去,那样它就会执行。
3.
$formatters也是一个执行它里面每一个元素(每一个元素都是一个函数)的数组,
主要用来对值进行格式化和转换,以便在绑定了这个值的控件中显示。
当数据的模型值发生变化的时候,里面的函数会被一一执行,
同样我们就可以将函数push进去,让它执行
4.
$viewChangeListeners的值也是一个由函数组成的数组
当视图的值发生变化的时候里面的函数会被一一调用,
实现跟$watch类似的功能。
5.
$render函数负责将模型值同步到视图上, 如果模型值被改变,需要同步视图的值。
6.
$setViewValue用于设置视图值(上面的例子就是将input的value值赋值给$viewValue)
7.
$error 一个包含所有error的对象
8.
$setPristine 设置为原始状态,会添加ng-pristine的class类名,移除ng-dirty的class类名
9.
$setValidity 来设置错误的标志
为一个函数,接受两个参数,第一个参数为错误标志的名字,是字符串类型,将会被设置成$error的属性
第二个参数为布朗值,为这个错误标志的值。
我们在控制台中打印出来ngmodel.$setValidity看看
function (validationErrorKey, isValid) { // Purposeful use of ! here to cast isValid to boolean in case it is undefined // jshint -W018 if ($error[validationErrorKey] === !isValid) return; // jshint +W018 if (isValid) { if ($error[validationErrorKey]) invalidCount--; if (!invalidCount) { toggleValidCss(true); this.$valid = true; this.$invalid = false; } } else { toggleValidCss(false); this.$invalid = true; this.$valid = false; invalidCount++; } $error[validationErrorKey] = !isValid; toggleValidCss(isValid, validationErrorKey); parentForm.$setValidity(validationErrorKey, isValid, this); }
可以了解到执行了ngmodel.$setValidity会影响到$invalid和$valid的值,
另外从上面代码中$error[validationErrorKey] = !isValid;可以知道,
执行之后,$error对象中的错误标志validationErrorKey为我们设置的布朗值isValid的相反值。
用通俗的话讲,用法就是ngmodel.$setValidity('flag',布朗值)
这样我们就可以在页面上用formname.inputname.$error.flag,例如:
<!DOCTYPE html> <html lang="en" ng-app="app"> <head> <meta charset="UTF-8"> <title>Document</title> <script src="angular.js" charset="utf-8"></script> </head> <body ng-controller='ctrl'> <form action="" name='myform'> <input type="text" test ng-model=_val name='jie'> <div ng-show='myform.jie.$error.empty'>empty!!</div> </form> <script> var app = angular.module('app',[]); app.controller('ctrl',function ($scope){ $scope._val = "leifengshushu"; }) app.directive('test',function(){ return{ restrict: 'AE', require: 'ngModel', link: function (scope,iElem,iAttr,ngmodel){ scope.$watch(function(){return scope._val},function(){ if(ngmodel.$isEmpty(ngmodel.$viewValue)){ ngmodel.$setValidity('empty',false); //注意到这里设置为false,而$error.empty则会显示为true console.log(ngmodel.$error); } }) //console.log(ngmodel.$setValidity); } } }) </script> </body> </html>
当你清空input里的值时候,这时候
<div ng-show='myform.jie.$error.empty'>empty!!</div>
就会显示出来。
10.
$name 的值为input的name属性的值,如下
<!DOCTYPE html> <html lang="en" ng-app="app"> <head> <meta charset="UTF-8"> <title>Document</title> <script src="angular.js" charset="utf-8"></script> </head> <body ng-controller='ctrl'> <input type="text" test ng-model=_val name='jie'> <script> var app = angular.module('app',[]); app.controller('ctrl',function ($scope){ $scope._val = "leifengshushu"; }) app.directive('test',function(){ return{ restrict: 'AE', require: 'ngModel', link: function (scope,iElem,iAttr,ngmodel){ console.log(ngmodel); console.log(ngmodel.$name); //输出jie } } }) </script> </body> </html>
11.
$$validityState(暂时不清楚用法,求解答~)
12.
$isEmpty(value) 函数,判断是否为空
当我们需要判断input的value值是否为空的时候,可以使用这个方法
其实可以就当它是个判断是否为空的方法,传入一个参数,判断这个参数是否为空,你传入任何值都可以
要是需要,我们也可以自己在指令里重写这个方法,来定义我们自己需要的“是否为空”的概念
13.
$pristine 如果用户还没有进行过交互,值是true.
$drity 如果用户已经进行过交互,值是true.
14.
$valid 如果没有错误,值是true.
$invalid 如果有错误,值是true.