zoukankan      html  css  js  c++  java
  • directive指令二 require:'^ngModel'

    本章主要是讲指令与ngModel的交互。

    在angular有一个内置指令叫ngModel,它是angular用来处理表单的最重要的指令。在源码中,页面上的model值的格式化、解析、验证都是由ngModel指令所对应的控制器ngModelController来实现的。ngModelController提供了很多方法和属性,我们可以通过自定义指令的require:'ngModel'来获取内置指令ngModel的ngModelController,进而在link函数里对操作ngModelController的方法和属性。

    接下来具体讲一下ngModelController的方法和属性,以及它们的具体用法。

     

    1.两个核心属性$viewValue和$modelValue 
    $viewValue是指令渲染模板所用的值,而$modelValue是在控制器中流通的值。很多时候这两个值是不一样的。比如说,当页面上展示了一个日期,显示的可能是"2018/04/23",但是这个字符串在控制器中对应的值可能是一个js的Date对象的实例。

     

    2.三个核心管道$formatters $parses $validators 和$asyncValidators 

     

    angular除了提供$viewValue和modelValue之外,还提供了两个用来处理它们的方法,分别是$parses和$formatters。 
    $parsers:由view值到model值的转换器,用户输入的变化会触发其中的管道函数,页面上的model值由管道函数中的return值决定。 
    $formatters:和$parsers的作用相反,它是model值到view值的转化器,其view值由对应的管道函数中的return值决定。 
    $validators: 是一个json对象

    {
       validateName: function(modelValue,viewValue){
           return ...
       }
    }

    当$setViewValue(value)被赋值给$modelValue之前,会经过$parsers管道,经过$parsers管道时,就会经过这个$validators管道。其中,validateName是验证器的名称,其中的参数modelValue和viewValue就是和viewValue,如果返回值是true,则通过validateName。 
    自定义一个验证器:

    <div class="alert alert-danger" role="alert" ng-show="myForm.myWidget.$error.validCharacters">
        <strong>Oh!</strong> 不符合自定义的验证规则!
    </div>
    ngModel.$validators.validCharacters = function(modelValue, viewValue) {
        var value = modelValue || viewValue;
        return /[0-9]+/.test(value);
    };

    $asyncValidators:也是一个json对象,不过可以用来处理异步验证。

    <input validate-name type="text" name="myWidget" ng-model="userContent" ng-model-options="{updateOn:'blur'}" class="form-control" required uniqueUsername>
    
    <div class="alert alert-danger" role="alert" ng-show="myForm.myWidget.$error.uniqueUsername">
          <strong>Oh!</strong> 已经存在的用户名!
    </div>
    app.directive('validateName',function($http,$q){
        return {
            restrict:'A',
            require:'?^ngModel',
            link:function(scope,iele,iattr,ctrl){
                ctrl.$asyncValidators.uniqueUsername = function(modelValue, viewValue) {
                    var value = modelValue || viewValue;
                    // 异步验证用户名是否已经存在
                    return $http.get('/api/users/' + value).
                    then(function resolved(res) {
                        if(res.data){
                            //用户名已经存在,验证失败,给下一个promise传递失败通知.
                            return $q.reject('res.data');
                        }
                        else {
                            //用户名不存在,验证成功.
                            return true
                        }
    
                    }, function rejected() {
                            //请求失败
                    })
                };
            }
        }
    });

     

    3.两个核心方法$setViewValue()和$render() 
    $setViewValue(): 更新视图值。原因是每个input的输入事件都会调用这个方法。但是如果value是一个对象,而不是字符串或数值,那么我们在用该方法传入值之前应该先拷贝一份,因为ngModel不会深入检测对象的变化,它只看对象的引用是否发生变化。如果只是改变了对象的某个属性,也不会去经过$parsers和$validators管道。执行$setViewValue()方法,不会触发$digest。 
    $render():在视图需要被更新的时候调用。由于ngModel的对比机制,$render()只在$modelValue和$viewValue都发生了实际的改变, 才会会被调用。也就是说,$render函数负责将模型值同步到视图上。

     

    来看一下指令和控制器及其内部运作如图: 
    ngModelController.PNG-49.8kB

    还有一些常用属性

    属性说明
    $error json对象。就是所有验证失败的验证名和失败信息组成的json对象。
    $pending json对象。正在进行中的异步验证会被放在这个对象里。
    $untouched 布尔值。如果元素还没有失去过焦点,那这个值就是true。
    $touched 布尔值。如果元素已经失去过焦点,那这个值就是false。
    $pristine 布尔值。如果元素还没有和用户发生过交互,那这个值就是true。
    $dirty 布尔值。如果元素已经和用户发生过交互,那这个值就是true。
    $valid 布尔值。这个也很常用,就是当所有验证(异步同步),都通过的时候,它就是true。
    $invalid 布尔值。这个也很常用,就是当所有验证(异步同步),其中有一个或一个以上验证失败,它就是true。
    $name 字符串。很简单,就是获取元素的name属性。
    $isEmpty 当我们需要判断input的value值是否为空的时候,可以使用这个方法。
  • 相关阅读:
    python爬虫之requests库
    python爬虫之urllib库
    fiddler配置及使用教程
    react中受控组件相关的warning
    Sublime Text 自动生成文件头部注释(版权信息):FileHeader 插件的使用
    手动安装sublime插件babel-sublime
    自定义组件 点击空白处隐藏
    pagination分页(支持首页,末页,跳转)
    vue打包以后,除了首页意外,其余页面是空白
    pm2踩过的坑
  • 原文地址:https://www.cnblogs.com/lyy-2016/p/8949537.html
Copyright © 2011-2022 走看看