zoukankan      html  css  js  c++  java
  • 学习笔记-AngularJs(八)

    在使用form.FormController和ngModel.NgModelController之前,先来学习一下怎么一个ng-model-options指令,觉得怎么这个指令挺好用的,我们知道ng-model是可以实现数据的双向绑定,至于双向数据绑定这个概念时必须要清楚的,都是这样的一个过程,view->scope和scope->view,只要双向绑定的element都是走怎么一个过程的,那么这个ng-model-options,就是可以实现对延迟更新、如何触发更新、时区(timezone针对input[type='date']等)等的控制,来看一下官网(http://t.cn/RUbL4rP这个不是,哈哈)的例子:

    //github上的block-example/表单操作-11/ng-model-options.html
    angular.module('optionsExample', []) .controller('ExampleController', ['$scope', function($scope) { $scope.user = { name: 'say', data: '' }; $scope.cancel = function(e) { if (e.keyCode == 27) { $scope.userForm.userName.$rollbackViewValue(); } }; }]);
    <div ng-controller="ExampleController">
      <form name="userForm">
        Name:
        <input type="text" name="userName"
               ng-model="user.name"
               ng-model-options="{ updateOn: 'blur',debounce: 1000 ,getterSetter: false  }"
               ng-keyup="cancel($event)" /><br />
    
        Other data:
        <input type="text" ng-model="user.data" /><br />
      </form>
      <pre>user.name = <span ng-bind="user.name"></span></pre>
    </div>

    updateOn:可以写入事件名字,将此element按所写事件触发更新

    debounce:当我们写进keydowm事件的时候,我需要的是它尽可能说是当我输入完毕后,再去触发更新,那么这个时候我们可以延迟个1s!

    getterSetter:为true的时候,则是指element的值是从函数return过来滴!

    我们看一下这里, $scope.userForm.userName.$rollbackViewValue(); userForm、userName是什么鬼?眼尖的可以看到是表单的name和input[name='userName'],那么其实可以怎么理解表单实例可以随意地使用name属性暴露到scope中,于是在$scope就可以使用表单实例了,便可以使用表单控制器的属性和方法了!

    form.FormController是啥?

    FormController跟踪所有input和form的各种状态的控制,如被有效/无效/已交互/未交互。官网文档:http://docs.angularjs.cn/api/ng/type/form.FormController

    其拥有的方法:

    $rollbackViewValue(); $commitViewValue(); $addControl(); $removeControl(); $setValidity(); $setDirty(); $setPristine(); $setUntouched(); $setSubmitted();

    $addControl()  //添加ngModel controller ,ngModel会自动添加,除非自定义指令或许会用上
    $removeControl()  //与$addControl()相反
    $setValidity()  //在自定义表单检验有着很大作用

    $rollbackViewValue() //这个我是这样理解的,回滚到上一个ViewValue

    拥有的属性:

    $pristine(form没被动过)  $dirty(form被动过) $valid(全部验证通过) $invalid(验证不通过) $submitted
    
    $error
        email、max、maxlength、min、minlength、number、pattern、required、url、date、datetimelocal、time、week、month

    给一个官网的例子(使用表单控制器的属性和方法怎么去验证input的正确性):

    
    
    //github上的block-example/表单操作-11/ng-form.html,其它类型的input[type=*]验证也都更新到github了
    <!doctype html>
    <html ng-app='formExample'>
        <head>
            <meta charset="utf8"/>
            <script src="http://code.angularjs.org/angular-1.0.1.min.js"></script>
            <style>
             .my-form {
               -webkit-transition:all linear 0.5s;
               transition:all linear 0.5s;
               background: transparent;
             }
             .my-form.ng-invalid {
               background: red;
             }
            </style>
            <script>
              angular.module('formExample', [])
                .controller('FormController', ['$scope', function($scope) {
                  $scope.userType = 'guest';
                  $scope.email = '739288994@qq.com';
    
                  var list = $scope.list = [];
    
                  $scope.submit = function() {
                         if($scope.userType){ list.push(this.userType);}
                         if($scope.email){  list.push(this.email);}    
                          // console.log(this.userType+","+this.email);
                          // console.log($scope.list);
                      };
                }]);
            </script>
        </head>
        <body>    
            <!--表单控制器-->
            <form name="myForm" ng-submit="submit()"  ng-controller="FormController" class="my-form" >
              userType: <input name="input" type="text" ng-model="userType" required>
              <span class="error" ng-show="myForm.input.$error.required">Required!</span><br>  <!--这里的意思是没有填的话就会显示-->
              email:  <input name="email" type="email"  ng-model="email">
                    <span class="error" ng-show="myForm.email.$error.email">Wrong Email!</span>
              <br> 
              <input type="submit" value="提交" id="submit" />
              <tt>userType = {{userType}}</tt><br>
              <tt>email = {{email}}</tt><br>
              <tt>myForm.input.$valid = {{myForm.input.$valid}}</tt><br> <!--表单的input的有效为true-->
              <tt>myForm.input.$error = {{myForm.input.$error}}</tt><br> <!--表单的input的$error-->
              <tt>myForm.email.$valid = {{myForm.email.$valid}}</tt><br> <!--表单的input的有效为true-->
              <tt>myForm.email.$error = {{myForm.email.$error}}</tt><br> <!--表单的input的$error-->
              <tt>myForm.$error.email = {{!!myForm.$error.email}}</tt><br> 
              <tt>myForm.$error.required = {{!!myForm.$error.required}}</tt><br>  <!--$error属性的required-->
              <tt>myForm.$valid = {{myForm.$valid}}</tt><br>        <!--有效效为true-->
              <tt>myForm.$invalid = {{myForm.$invalid}}</tt><br>    <!--无效为true-->
              <tt>myForm.$pristine= {{myForm.$pristine}}</tt><br>   <!--与表单有相互作用为true-->
              <tt>myForm.$dirty= {{myForm.$dirty}}</tt><br>   <!--与表单无相互作用为true-->
              <tt>myForm.$submitted = {{myForm.$submitted}}</tt><br>   
              <tt>提交的数据:{{list|json}}</tt>
             </form>
        </body>
    </html>
    
    <!-- If the name attribute is specified, the form controller is published onto the current scope under this name. -->
    
    <!--表单阻止了表单默认action提交的方式,改用ng-submit或ng-click对表单进行绑定,具体操作看列子-->
    
    <!-- <form [name=""]>...</form> 等价于 <div ng-form='##'></div> 控制器为name属性的值 -->

    具体可以看代码!

    ngModel.NgModelController是啥?

    NgModelController 为ngModel指令提供了API。该控制器包含数据双向绑定服务、验证、Value格式化和解析、CSS更新。它不包含任何逻辑处理DOM渲染或DOM event,这样的DOM相关逻辑应使用其他指令,NgModelController用来控制元素的数据绑定。Angular默认提供许多关于input元素 DOM逻辑处理。官网文档:http://docs.angularjs.cn/api/ng/type/ngModel.NgModelController

    其拥有的方法:

    $render(); $isEmpty(value); $setValidity(validationErrorKey, isValid); $setPristine(); $setDirty(); $setUntouched(); $setTouched(); $rollbackViewValue(); $validate(); $commitViewValue(); $setViewValue(value, trigger);

    $render: angular 会把 $modelValue 经过 $formatters 得出来的值放入 $viewValue中,(这时 $viewValue = $modelValue 经过 $formatters) 然后触发我们写好的 $render . 跟着$setViewValue(value, trigger);一起使用。

    $setViewValue:scope改变$modelValue,使用$setViewValue(),改变$viewValue

    $setValidity:使用这个配合$parsers可以实现表单自定义验证

    拥有的属性:

    $viewValue  //界面显示的数据

    $modelValue //$scope上面的value

    $parsers //在
    view->model的时候会触发的一个函数组,无论什么时候Model发生改变,所有的ngModelController.$formatters(model发生改变时触发数据有效验证和格式化转变)数组中的function将排队执行,所以在这里每一个function都有机会去格式化model的值,并且通过NgModelController.$setValidity修改空间的验证状态。


    $formatters //
    model->view的时候会触发的一个函数组, 无论任何时候用户与控件发生交互,将会触发NgModelCtroller.$setViewValue。这时候轮到执行NgModelController.$parsers(当控件从dom取值之后,将会执行这个数组中的所有方法,对值进行审查过滤或转换,也进行验证)数组中的所有方法。


    $validators
    $asyncValidators
    $viewChangeListeners
    $error
    $pending
    $untouched
    $touched
    $pristine
    $dirty
    $valid
    $invalid
    $name

     那么多个属性都差不多,是不是关系很密切勒!双向绑定的机制可以在$parsers和$formatters可以体现出来,通过这些我们可以在view->scope做类似表单验证(自定义)的功能(配合$setValidity(validationErrorKey, isValid);),scope->view数据格式自定义等操作(配合$setViewValue(value, trigger);),可以看一下下面的这个例子(https://github.com/xiaobin5201314/AngularJS-Learning/blob/master/block-example/表单操作-11/ng-model.html):

    
    

    var custom = angular.module('customControl', ['ngSanitize']);

    custom.directive("noxiaobin", function () {
    return {
    restrict: "A",
    require: "?ngModel",
    link: function (scope, element, attrs, ngModel) {
    if (!ngModel) return;
    ngModel.$parsers.push(function (v) { //传说中的验证器

    if (v != "xiaobin") {
    ngModel.$setValidity('noxiaobin', true); //通过获取从dom过来的值,然后进行验证,使用$setValidity('noxiaobin', true);改变noxiaobin的值,然后反馈会dom
    return v;
    } else {
    ngModel.$setValidity('noxiaobin', false);
    return undefined;
    }

    });
    }
    }
    });

    
    

    custom.directive('contenteditable', ['$sce', function($sce) {
    return {
    restrict: 'A', //指定该指令是为属性类型的指令
    require: '?ngModel', // 与ngModel指令的相互交流
    link: function(scope, element, attrs, ngModel) { //scope分别是指令作用的作用域,element触发指令的元素,attrs是element的属性集合,ngmodel是控制器就是引入的ngModel
    if (!ngModel) return;

    
    

    // output data to the view
    ngModel.$render = function() {
    element.html($sce.getTrustedHtml(ngModel.$viewValue || '')); //$viewValue的值进行format
    };

    
    

    //对element的监听
    element.on('blur keyup change', function() {
    scope.$evalAsync(read); //执行read方法
    });
    read(); // 初始化

    
    

    // Write data to the model
    function read() {
    var html = element.html();
    // When we clear the content editable the browser leaves a <br> behind
    // If strip-br attribute is provided then we strip this out
    if ( attrs.stripBr && html == '<br>' ) {
    html = '';
    }

    
    

    ngModel.$setViewValue(html); //获取ViewValue,设置$viewValue
    }

    }
    };
    }]);

     
        <form name="myForm">
             <div contenteditable 
                  name="myWidget" ng-model="userContent"
                  strip-br="true"
                  required>点击编辑</div>
              <span ng-show="myForm.myWidget.$error.required">Required!</span>
    
              <input type="text" name="email" ng-model="email" noxiaobin />
              <span ng-show="myForm.email.$error.noxiaobin">Value nerver have xiaobin!</span>
             <hr>
             <textarea ng-model="userContent"></textarea>
        </form>

     以上有两个指令分别是

    1、view->scope,配合$setValidity(validationErrorKey, isValid);进行表单验证,通过反馈回view的noxiaobin来判断是否显示

    2、scope->view,使用$setViewValue(value, trigger);设置view的值,然后触发$render,对其进行格式化

    3、代码下载:https://github.com/xiaobin5201314/AngularJS-Learning

    对于ngModel.NgModelController确实有些绕,也有些地方还是不懂,不过也有些文章写得还是比较明晰的,如:http://sentsin.com/web/659.html,如果对ngModel.NgModelController有那些更加全,或是更加详细的资料可以拿给我学习学习!!!

  • 相关阅读:
    MySQL limit 分页查询优化(百万级优化)
    HAVING 搜索条件在进行分组操作之后应用
    Mysql 多表连接查询 inner join 和 outer join 的使用
    php7 configure: error: Cannot find OpenSSL's <evp.h> 问题解决
    解决Cannot find config.m4 Make sure that you run '/home/php/bin/phpize' in the top level source directory of the module
    Ubuntu下彻底卸载默认安装的mysql,自己手动下载安装MYSQL
    mysql 运算操作符
    mysql 函数表
    【mysql】连接和断开服务器
    mysql 5.7 增删改查及别名的用法
  • 原文地址:https://www.cnblogs.com/wuxiaobin/p/4838577.html
Copyright © 2011-2022 走看看