angular指令中的require: 'ngModel'

来源:互联网 发布:沼泽人 知乎 编辑:程序博客网 时间:2024/06/06 11:15

在说require之前,先看一下scope

指令scope: false, true,{}:
1. false:默认使用controller的scope;<br>
2. true:独立作用域,但是包含父scope的属性和方法;
3. {} 使用独立的scope;<br>
3.1. 绑定父作用域的scope,请参考绑定策略;

 

require表示需要依赖的指令;如果有依赖的指令,那么link的第四个参数也就是依赖指令的对外暴露的controller也自动会被注入进来

require选项的值可以分别用前缀?、^ 和?^进行修饰,也可以不修饰。
如果不进行修饰,比如require:'thisDirective',那么require只会在当前指令中查找控制器
如果想要指向上游的指令,那么就是用^进行修饰,比如require:'^parentDirective',如果没有找到,那就会抛出一个错误。
如果使用?前缀,就意味着如果在当前指令没有找到控制器,就将null作为link的第四个参数;
那么,如果将?和^结合起来,就可以既指定上游指令,又可以在找不到时,不抛出严重的错误。

 

自定义指令是当使用require:‘ngModel’ 这个选项来增强对表单的操作,这样ngModel就可以作为link选项的第四个参数,

1
2
3
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.