• 深入了解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);
      }
    View Code

    可以了解到执行了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>
    View Code

    11.

    $$validityState(暂时不清楚用法,求解答~)

    12.

    $isEmpty(value) 函数,判断是否为空

    当我们需要判断input的value值是否为空的时候,可以使用这个方法

    其实可以就当它是个判断是否为空的方法,传入一个参数,判断这个参数是否为空,你传入任何值都可以

    要是需要,我们也可以自己在指令里重写这个方法,来定义我们自己需要的“是否为空”的概念

     13. 

    $pristine 如果用户还没有进行过交互,值是true.

    $drity 如果用户已经进行过交互,值是true.

     14.

    $valid 如果没有错误,值是true.

    $invalid 如果有错误,值是true.

  • 相关阅读:
    float
    老师的通病
    无题
    BufferedReader
    剩余定理
    ActionScript 多图加载 按图顺序索引
    C++ Socket 编程
    设计高可用和高负载的网站系统
    提高网站速度的最佳实践【翻译】
    把哈希表存储到数据库中
  • 原文地址:https://www.cnblogs.com/cunjieliu/p/4231353.html
Copyright © 2020-2023  润新知