AngularJS开发指南6:AngularJS表单详解

表单控件(input, select, textarea )是用来获取用户输入的。表单则是一组有联系的表单控件的集合。

用户能通过表单和表单控件提供验证的服务,知道自己的输入是否合法。这样能让用户交互变得友好,因为用户能通过反馈来修正自己的错误。不过,虽然客户端的验证能够起到很大作用,但也很容易被绕过,所以不能完全依靠客户端验证。 要建立安全的应用,服务器端验证还是必不可少的。

了解AngularJS双向绑定的关键在于了解ngModel指令。这个指令通过动态将model和view互相映射,来实现双向绑定。

为了能美化表单和表单元素,ngModel指令会自动为元素添加以下css类:

  • ng-valid
  • ng-invalid
  • ng-pristine
  • ng-dirty

一个表单就是一个FormController的实例,表单实例可以通过name属性选择性地公开到作用域中。同样的,一个表单控件也是一个NgModelController的实例,表单控件也能同样的被公开到作用域中。这意味视图能通过绑定的基本功能获取表单或者表单控件的状态。

  • 只有当表单发生改变时,重置按钮才会被显示出来。
  • 只有当表单有改变并且改变的值都是合法的,保存按钮才会被显示出来。
  • 能自定义user.email和user.agree的错误信息。

举个例子:

<!doctype html>
<html ng-app>
  <head>
    <script src="http://code.angularjs.org/angular-1.0.2.min.js"></script>
    <script>
        function Controller($scope) {
        $scope.master= {};
        $scope.update = function(user) {
            $scope.master= angular.copy(user);
        };
        $scope.reset = function() {
            $scope.user = angular.copy($scope.master);
        };
        $scope.isUnchanged = function(user) {
            return angular.equals(user, $scope.master);
        };
        $scope.reset();
    }
    </script>
  </head>
  <body>
    <div ng-controller="Controller">
      <form name="form" class="css-form" novalidate>     //novalidate是用来屏蔽浏览器本身的验证功能的。
        Name:
          <input type="text" ng-model="user.name" name="uName" required /><br />    //required,此输入框必须有内容
        E-mail:
          <input type="email" ng-model="user.email" name="uEmail" required/><br />
        <div ng-show="form.uEmail.$dirty && form.uEmail.$invalid">Invalid:           //此div,如果form表中的name为uEmail的input元素中的内容违法或者是脏数据,那么就显示出来。
          <span ng-show="form.uEmail.$error.required">Tell us your email.</span>     //如果错误信息是由required引起的,就显示此span
          <span ng-show="form.uEmail.$error.email">This is not a valid email.</span>    //如果错误信息是由里面的内容不合法引起的,就显示此span
        </div>

        Gender: <input type="radio" ng-model="user.gender" value="male" />male
        <input type="radio" ng-model="user.gender" value="female" />female<br />

        <input type="checkbox" ng-model="user.agree" name="userAgree" required />
        I agree: <input ng-show="user.agree" type="text" ng-model="user.agreeSign"
                  required /><br />
        <div ng-show="!user.agree || !user.agreeSign">Please agree and sign.</div>

        <button ng-click="reset()" ng-disabled="isUnchanged(user)">RESET</button>
        <button ng-click="update(user)" ng-disabled="form.$invalid || isUnchanged(user)">SAVE</button>  //如果整个form表单没有通过验证或者form表单中的内容没有发生改变,此按钮就不可点击
      </form>
    </div>
  </body>
</html>

AngularJS实现了大部分常见的html5表单输入元素(text, number, url, email, radio, checkbox),也实现了很多用于验证的指令(required, pattern, minlength, maxlength, min, max)。

如果想要定义你自己的验证器的话,可以通过在你自己的指令中添加一个验证函数给ngModel的控制器来实现。要想获得控制器的引用,需要在指令中指定依赖,验证函数可以写在两个地方。

  • 模型到视图的更新中- 只要绑定的模型改变了,NgModelController#$formatters数组中的函数就会被轮流调用,所以每一个函数都有机会对数据进行格式化,当然你也可以通过NgModelController#$setValidity来改变表单的验证状态。
  • 视图到模型的更新中- 相同的,只要用户与表单交互了,NgModelController#$setViewValue就会被调用。 这次是NgModelController#$parsers数组中的函数会被依次调用,每个函数都有机会来改变值或者通过NgModelController#$setValidity来改变表单的验证状态。下面的例子,使用的是这个。

举个例子:

<!doctype html>
<html ng-app="form-example1">
  <head>
    <script src="http://code.angularjs.org/angular-1.0.2.min.js"></script>
    <script>
          var app = angular.module(‘form-example1‘, []);
      var INTEGER_REGEXP = /^\-?\d+$/;   //或者以"-"(负)开头,或者没有负号,后面都是正整数,包括0
      app.directive(‘integer‘, function() {
         return {
            require: ‘ngModel‘,    //依赖nogModel指令
            link: function(scope, elm, attrs, ctrl) {
                ctrl.$parsers.unshift(function(viewValue) {      //ctrl可以调用ngModel指令中controller函数中定义的方法
                    if (INTEGER_REGEXP.test(viewValue)) {
                        ctrl.$setValidity(‘integer‘, true);
                        return viewValue;
                    } else {
                        ctrl.$setValidity(‘integer‘, false);
                        return undefined;
                    }
                });
            }
         };
      });
      var FLOAT_REGEXP = /^\-?\d+((\.|\,)\d+)?$/;  //可以是正负,可以是整数,也可以是浮点数,浮点数可以用"."分开,也可以用","分开。
      app.directive(‘smartFloat‘, function() {
         return {
            require: ‘ngModel‘,
            link: function(scope, elm, attrs, ctrl) {
                ctrl.$parsers.unshift(function(viewValue) {
                    if (FLOAT_REGEXP.test(viewValue)) {
                        ctrl.$setValidity(‘float‘, true);
                        return parseFloat(viewValue.replace(‘,‘, ‘.‘));
                    } else {
                        ctrl.$setValidity(‘float‘, false);
                        return undefined;
                    }
                });
            }
         };
      });
    </script>
  </head>
  <body>
    <div ng-controller="Controller">
      <form name="form" class="css-form" novalidate>
        <div>
          Size (integer 0 - 10):
          <input type="number" ng-model="size" name="size" min="0" max="10" integer />{{size}}<br />   //integer,自定义指令
          <span ng-show="form.size.$error.integer">This is not valid integer!</span>
          <span ng-show="form.size.$error.min || form.size.$error.max">The value must be in range 0 to 10!</span>
        </div>

        <div>
          Length (float):
          <input type="text" ng-model="length" name="length" smart-float />{{length}}<br />   //smart-float,自定义指令
          <span ng-show="form.length.$error.float">This is not a valid float number!</span>
        </div>
      </form>
    </div>
  </body>
</html>

上面的例子中,我们创建了两个指令。

  • 第一个指令是要验证输入的是否是整数。例如,1.23就不符合验证的值,因为它包含了分数部分。
  • 第二个指令是要验证输入的是否是“智能浮点(smart-float)”。它能把"1.2"或者"1,2"都转化为合法的浮点数"1.2"。注意,这里我们不能使用input元素的type="number",因为支持HTML5的浏览器不允许用户输入像"1,2"这样的非法值。

AngularJS已经实现了所有基本的HTML表单控件(input,select,textarea),对于大部分情况应该已经够了。但是,你还是可以通过写指令来实现你自己的表单控件。

要和ngModel指令协同工作实现自定义控件,并且实现双向绑定的话,需要:

  • 实现render方法。这个方法负责在数据模型变化时,把变化的值传递给NgModelController#$formatters后,用来在view上渲染新的数据。
  • 在用户与控件交互并且模型需要被更新时,调用$setViewValue方法。这通常是在DOM的监听事件中完成的。

下面的例子演示了如何添加一个“内容可编辑”的数据双向绑定的元素。

<!doctype html>
<html ng-app="form-example2">
  <head>
    <script src="http://code.angularjs.org/angular-1.0.2.min.js"></script>
    <script>
       angular.module(‘form-example2‘, []).directive(‘contenteditable‘, function() {   //自定义指令contenteditable
        return {
            require: ‘ngModel‘,
            link: function(scope, elm, attrs, ctrl) {
                // view -> model
                elm.bind(‘blur‘, function() {   //给元素div绑定blur事件
                   scope.$apply(function() {
                      ctrl.$setViewValue(elm.html());   //当输入结束后,焦点离开div元素时,就更新model
                    });
                 });
                // model -> view
                ctrl.$render = function(value) {
                    elm.html(value);            //更新视图view
                };
                // load init value from DOM
                ctrl.$setViewValue(elm.html());
            }
        };
    });
    </script>
  </head>
  <body>
    <div contentEditable="true" ng-model="content" title="Click to edit">Some</div>
    <pre>model = {{content}}</pre>
    <style type="text/css">
      div[contentEditable] {
        cursor: pointer;
        background-color: #D0D0D0;
      }
    </style>
  </body>
</html>

加油!

时间: 2024-10-27 00:13:55

AngularJS开发指南6:AngularJS表单详解的相关文章

AngularJS开发指南4:指令的详解

指令是我们用来扩展浏览器能力的技术之一.在DOM编译期间,和HTML元素关联着的指令会被检测到,并且被执行.这使得指令可以为DOM指定行为,或者改变它. AngularJS有一套完整的.可扩展的.用来帮助web应用开发的指令集,它使得HTML可以转变成“特定领域语言(DSL)”. 指令可以做为HTML中的元素名,属性名,类名,或者注释.下面是一些等效调用myDir指令的例子: <span my-dir="exp"></span> <span class=&

提交表单详解

阅读目录 简单的表单,简单的处理方式 表单提交,成功控件 多提交按钮的表单 上传文件的表单 MVC Controller中多个自定义类型的传入参数 F5刷新问题并不是WebForms的错 以Ajax方式提交整个表单 以Ajax方式提交部分表单 使用JQuery,就不要再拼URL了! id, name 有什么关系 使用C#模拟浏览器提交表单 资源链接 Form(表单)对于每个WEB开发人员来说,应该是再熟悉不过的东西了,可它却是页面与WEB服务器交互过程中最重要的信息来源. 虽然Asp.net W

HTML5之表单详解

请在新版标准浏览器(Chrome/Opera/Firefox/Safari...)中浏览本文中的样例,否则你看到的只是一个个空白的表单! ⊙﹏⊙|∣ 时光车轮滚滚碾来,前端之路永无止歇.对于这个前端这门精一多专的技术,任何一次技术革新,我们都必须第一时间去了解它学习它,比如Web世界里这簇美艳的花朵---HTML5.虽然HTML5发布之初,许多人(包括我)都觉得普及它还很遥远,但自发布以来,许多企业级网站对它的尝试应用(比如<!doctype html>应用,比如canvas的应用),使HTM

form表单详解

表单属性   属性                          值                                           描述 accept                 MIME_type               规定通过文件上传来提交的文件的类型 accept-charset     charset                     服务器处理表单数据所接受的字符集 enctype                MIME_type      

移动IM开发指南2:心跳指令详解

<移动IM开发指南>系列文章将会介绍一个IM APP的方方面面,包括技术选型.登陆优化等.此外,本文作者会结合他在网易云信多年iOS IM SDK开发的经验,深度分析实际开发中的各种常见问题. 推荐阅读 移动IM开发指南1:如何进行技术选型 移动IM开发指南3:如何优化登录模块 心跳指令是什么? 在使用 TCP 长连接的 IM 服务设计中,往往都会涉及到心跳.心跳一般是指某端(绝大多数情况下是客户端)每隔一定时间向对端发送自定义指令,以判断双方是否存活,因其按照一定间隔发送,类似于心跳,故被称

3 表单详解

html表单 为什么: 提交数据给后台 <form> <input> 元素是最重要的表单元素,每个<input>元素必须写一个 name 属性,不然不会被提交 组合表单元素<fieldset> <form action="action_page.php" method="GET> <fieldset>//组合表单的输入元素 <legend>Personal information:</l

react学习笔记(二)React表单详解

一.不可控组件和可控组件介绍 什么是不可控组件 <input type="text" defaultValue="Hello World" />var inputValue = ?var inputValue = React.findDOMNode(this.refs.input).value 什么是可控组件 <input type="text" defaultValue={this.state.value} /> var

AngularJS开发指南7:AngularJS本地化,国际化,以及兼容IE低版本浏览器

AngularJS本地化,国际化 国际化,简写为i18n,指的是使产品快速适应不同语言和文化. 本地化,简称l10n,是指使产品在特定文化和语言市场中可用. 对开发者来说,国际化一个应用意味着将所有的文字和其他因地区而异的数据从应用中抽离出来. 本地化意味着为这些抽离的数据和文字提供翻译和转变成本地的格式. 目前,AngularJS支持日期,数字和货币的国际化和本地化. 另外,AngularJS还通过ngPluralize指令支持本地多元化. 所有的AngularJS本地化组件都依赖于$loca

Angularjs开发指南

Angularjs开发指南:http://docs.ngnice.com/guide Angularjs中文网:http://www.apjs.net/