美文网首页
form指令

form指令

作者: yb_剑笙 | 来源:发表于2016-09-17 05:20 被阅读0次

    概述

    Angular JS的form指令提供表单相关的功能,它有两种形式:form和ng-form。
    form和ng-form几乎是一模一样的,只有很小的一点区别:

    form ng-form
    只有E模式 有EAC三种模式
    只会判断和监测name属性 会判断和监测name和ng-form属性,悠闲name属性

    实现细节

    必要的时候监听submit事件

    如果没有设置action属性时,form指令会监听submit事件,然后添加默认的响应。

    if (!('action' in attr)) {
        var handleFormSubmission = function(event) {
            scope.$apply(function() {
                controller.$commitViewValue();
                controller.$setSubmitted();
            });
    
            event.preventDefault();
        };
    
        formElement[0].addEventListener('submit', handleFormSubmission);
    
        formElement.on('$destroy', function() {
            $timeout(function() {
              formElement[0].removeEventListener('submit', handleFormSubmission);
            }, 0, false);
        });
    }
    

    代码中最关键的是调用$commitViewValue和$setSubmitted函数,这两个函数实现了更新数据和设置已提交标识。这里的controller实际上是form指令的controller。
    $commitViewValue只是调用子controller的$commitViewValue,form controller的子controller只有子form和ng-model的controller,所以最终调用的是ng-model的controller里的¥commitViewValue,具体将在ng-model指令里分析。
    $setSubmitted功能更加简单,为form元素添加ng-submitted的css类,然后设置submitted标记为true,最后调用父form controller的$setSubmitted方法。

    和父form建立关系

    在form指令link的pre里,会把自己的controller添加到父form的controller里去,实现父子form的关联关系,如果没有父form,就什么也不做。
    添加的过程:

    form.$addControl = function(control) {
      // Breaking change - before, inputs whose name was "hasOwnProperty" were quietly ignored
      // and not added to the scope.  Now we throw an error.
      assertNotHasOwnProperty(control.$name, 'input');
      controls.push(control);
    
      if (control.$name) {
        form[control.$name] = control;
      }
    
      control.$$parentForm = form;
    };
    

    其中control.$name为name或者ng-form属性的值,计算过程为:

    form.$name = $interpolate(attrs.name || attrs.ngForm || '')($scope);
    

    从这个添加过程可以看出,在父controller中会记录一个子controller列表,如果子controller设置了name属性,父controller还会添加对应名称的属性值(可以实现数据绑定,具体实现过程为:监测name属性,调用rename方法)。
    同时在子controller中也会记录下父的form。这个过程是后续form指令各种操作的基础,他保证了表单操作时上下级的关联关系。

    form controller中定义的方法

    在form controller中定义了一些列的form操作方法,可以分为三大类:
    1、controller关系操作,包括:$addControl,$removeControl,$$renameControl
    2、controller对数据的操作,这个部分一般都是向下递归调用,最终调用ng-model中对应的函数,包括:$commitViewValue,$rollbackViewValue
    3、form状态操作,这部分的方法一般都是递归调用,设置状态和css类,包括:$setPristine,$setUntouched,$setSubmitted,$setDirty。

    form指令中支持的css类

    在form指令中随着数据状态的变化,会自动的添加对应的css类,从而支持对于不同状态下的样式控制,其支持的css类有:

    css类名 说明
    ng-valid 全部数据都是有效的
    ng-invalid 有无效的数据
    ng-pending 表单处理中的状态
    ng-pristine 数据是干净的,与dirty相对
    ng-dirty 数据被修改过
    ng-submitted 数据已经被提交过

    代码样例

    <!DOCTYPE html>
    <html lang="en" ng-app="app">
    <!--<html>-->
    <head>
        <title>Test</title>
    </head>
    <body>
    <style>
        .my-form {
            transition:all linear 0.5s;
            background: transparent;
        }
        .my-form.ng-invalid {
            background: red;
        }
    </style>
    <form name="myForm" ng-controller="ExampleController" class="my-form">
        userType: <input name="input" ng-model="userType" required>
        <span class="error" ng-show="myForm.input.$error.required">Required!</span><br>
        <code>userType = {{userType}}</code><br>
        <code>myForm.input.$valid = {{myForm.input.$valid}}</code><br>
        <code>myForm.input.$error = {{myForm.input.$error}}</code><br>
        <code>myForm.$valid = {{myForm.$valid}}</code><br>
        <code>myForm.$error.required = {{!!myForm.$error.required}}</code><br>
    </form>
    <script src="./node_modules/angular/angular.js" type="text/javascript"></script>
    <script>
        angular.module('app', [])
                .controller('ExampleController', ['$scope', function ($scope) {
                    $scope.userType = 'guest';
                }]);
    </script>
    </body>
    </html>
    

    这段代码实现了form指令的基本功能,会判断表单输入项的合法性。如果输入为空,背景就会为红色。

    相关文章

      网友评论

          本文标题:form指令

          本文链接:https://www.haomeiwen.com/subject/whwiettx.html