详细分析使用AngularJS编程中提交表单的方式

在AngularJS出现之前,很多开发者就面对了表单提交这一问题。由于提交表单的方式繁杂而不同,很容易令人疯掉……然而现在看来,依然会让人疯掉。

今天,我们会看一下过去使用PHP方式提交的表单,现在如何将其转换为使用Angular提交。使用Angular来处理表单,对我而言,是一个“啊哈”时刻(译者:表示了解或发现某事物的喜悦)。即使它甚至都没有涉及多少Angular表层的东西,但是它却帮助用户看到表单提交之后的潜力,并且理解两种数据绑定方式。

我们会使用jQuery平台来进行这个处理过程。所以所要做的工作首先使用javascript。我们会提交表单,展示错误信息,添加错误类,并且在javascript中显示和隐藏信息。

之后,我们会使用Angular。在使用之前,我们要做大部分所需的工作,并且我们之前所做的很多工作会非常容易。让我们开始吧。

简单的表单

我们会关注两种提交表单的方式:

  • 旧方法:jQuery和PHP提交表单
  • 新方法:AngularJS和PHP提交表单

首先看一下我们的表单,超级简单:

形式要求

  • 实现页面无刷新表单处理
  • 输入姓名和超级英雄别名
  • 如果有错误,显示错误提示
  • 如果输入有误,将输入变成红色
  • 如果所有内容ok,显示成功提示

文档结构

在我们的展示中,仅需两个文件

  • index.html
  • process.php


表单处理

让我们新建一个PHP来处理表单。该页面非常小并且使用POST方式提交数据。

处理表单:这对我们来说并不是那么重要的。你可以使用其他你喜欢的语言来处理你的表单。

// process.php

<?php

$errors   = array();  // array to hold validation errors
$data    = array();   // array to pass back data

// validate the variables ======================================================
 if (empty($_POST['name']))
  $errors['name'] = 'Name is required.';

 if (empty($_POST['superheroAlias']))
  $errors['superheroAlias'] = 'Superhero alias is required.';

// return a response ===========================================================

 // response if there are errors
 if ( ! empty($errors)) {

  // if there are items in our errors array, return those errors
  $data['success'] = false;
  $data['errors'] = $errors;
 } else {

  // if there are no errors, return a message
  $data['success'] = true;
  $data['message'] = 'Success!';
 }

 // return all our data to an AJAX call
 echo json_encode($data);

这是一个非常简单的表单处理脚本。我们仅检查数据是否存在,如果存在,则不做任何处理和操做;如果不存在,则需要向$errors数组中添加一条信息。

为了返回我们的数据用于AJAX调用,我们需要使用echo和json_encode。这就是我们PHP表单处理所有需要做的操作。使用普通的jQuery AJAX或者Angular处理表单也是这样的。
 展示表单

让我们创建一个HTML来展示我们的表单

<!-- index.html -->

<!doctype html>
<html>
<head>
 <title>Angular Forms</title>

 <!-- LOAD BOOTSTRAP CSS -->
 <link rel="stylesheet" href="//netdna.bootstrapcdn.com/bootstrap/3.0.2/css/bootstrap.min.css">

 <!-- LOAD JQUERY -->
  <!-- when building an angular app, you generally DO NOT want to use jquery -->
  <!-- we are breaking this rule here because jQuery's $.param will help us send data to our PHP script so that PHP can recognize it -->
  <!-- this is jQuery's only use. avoid it in Angular apps and if anyone has tips on how to send data to a PHP script w/o jQuery, please state it in the comments -->
  <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.0.3/jquery.min.js"></script>

 <!-- PROCESS FORM WITH AJAX (OLD) -->
 <script>
  <!-- WE WILL PROCESS OUR FORM HERE -->
 </script>
</head>
<body>
<div class="container">
<div class="col-md-6 col-md-offset-3">

 <!-- PAGE TITLE -->
 <div class="page-header">
  <h1><span class="glyphicon glyphicon-tower"></span> Submitting Forms with Angular</h1>
 </div>

 <!-- SHOW ERROR/SUCCESS MESSAGES -->
 <div id="messages"></div>

 <!-- FORM -->
 <form>
  <!-- NAME -->
  <div id="name-group" class="form-group">
   <label>Name</label>
   <input type="text" name="name" class="form-control" placeholder="Bruce Wayne">
   <span class="help-block"></span>
  </div>

  <!-- SUPERHERO NAME -->
  <div id="superhero-group" class="form-group">
   <label>Superhero Alias</label>
   <input type="text" name="superheroAlias" class="form-control" placeholder="Caped Crusader">
   <span class="help-block"></span>
  </div>

  <!-- SUBMIT BUTTON -->
  <button type="submit" class="btn btn-success btn-lg btn-block">
   <span class="glyphicon glyphicon-flash"></span> Submit!
  </button>
 </form>

</div>
</div>
</body>
</html>

现在,我们有了表单。我们另外还使用了Bootstrap来使表单看起来不是那么丑。使用Bootstrap语法规则,每个input下含有一个spot来展示我们文本的错误信息。

使用jQuery提交表单

现在,让我们来使用jQuery处理表单提交。我会将所有的代码添加到空的<script>标签中

<!-- index.html -->

...

 <!-- PROCESS FORM WITH AJAX (OLD) -->
 <script>
  $(document).ready(function() {

   // process the form
   $('form').submit(function(event) {

    // remove the past errors
    $('#name-group').removeClass('has-error');
    $('#name-group .help-block').empty();
    $('#superhero-group').removeClass('has-error');
    $('#superhero-group .help-block').empty();

    // remove success messages
    $('#messages').removeClass('alert alert-success').empty();

    // get the form data
    var formData = {
     'name'     : $('input[name=name]').val(),
     'superheroAlias'  : $('input[name=superheroAlias]').val()
    };

    // process the form
    $.ajax({
     type   : 'POST',
     url   : 'process.php',
     data   : formData,
     dataType  : 'json',
     success  : function(data) {

      // log data to the console so we can see
      console.log(data);

      // if validation fails
      // add the error class to show a red input
      // add the error message to the help block under the input
      if ( ! data.success) {

       if (data.errors.name) {
        $('#name-group').addClass('has-error');
        $('#name-group .help-block').html(data.errors.name);
       }

       if (data.errors.superheroAlias) {
        $('#superhero-group').addClass('has-error');
        $('#superhero-group .help-block').html(data.errors.superheroAlias);
       }

      } else {

       // if validation is good add success message
       $('#messages').addClass('alert alert-success').append('<p>' + data.message + '</p>');
      }
     }
    });

    // stop the form from submitting and refreshing
    event.preventDefault();
   });

  });
 </script>

...

这里处理表单有不少的代码。我们有获取表单中变量的代码,有使用AJAX将数据发送至我们的表单的代码,有检查是否有错和显示成功提示的代码。除此之外,我们希望每次表单提交之后,过去的错误信息都会被清除。确实是不少代码。

现在,如果表单中含有错误,则:

如果提交成功:

现在,让我们看使用Angular来提交相同的表单。记住,我们不需要更改任何关于我们的PHP如何处理表单的内容,我们的应用依然会具备相同的功能(在同一个地方展示错误和成功信息)。

使用Angular提交表单

我们准备在之前使用的<script>标签中设置我们的Angular应用。所以删除里面的内容,我们就可以开始了。
设置一个Angular应用

步骤为:

1. 加载Angular

2. 设置module

3. 这是controller

4. 将module和controller应用于HTML

5. 设置双向变量绑定

6. 这是错误和信息

看起来好像是很多内容,但是最终,我们会用非常少的代码,并且看起来会非常简洁。另外,创建带有更多输入更大的表单,也会更容易。

Angular 组件和控制器

首先,加载Angular并且新建组件和控制器

<!-- index.html -->

...

 <!-- LOAD JQUERY -->
 <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.0.3/jquery.min.js"></script>
 <!-- LOAD ANGULAR -->
 <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.0/angular.min.js"></script>

 <!-- PROCESS FORM WITH AJAX (NEW) -->
 <script>

  // define angular module/app
  var formApp = angular.module('formApp', []);

  // create angular controller and pass in $scope and $http
  function formController($scope, $http) {

  }

 </script>
</head>

<!-- apply the module and controller to our body so angular is applied to that -->
<body ng-app="formApp" ng-controller="formController">

...

现在,我们有了Angular应用的基础。我们已经加载了Angular,创建了组件模块和控制器,并且将其应用于我们的网站。

接下来,我将展示双向绑定是如何工作的。

双向数据绑定

这是Angular的核心思想之一,也是功能最强大的内容之一。在Angular文档中,我们看到:“在Angular网页应用中的数据绑定,是模型和视图层之间的数据自动同步。”这意味着,我们需要在表单中抓取数据,使用$('input[name=name]').val()并不是必需的。

我们在Angular中将数据和变量绑定在一起,无论是javascript也好,view也罢,只要有改变,两者皆变。

为了演示数据绑定,我们需要获取表单的input来自动填充变量formData。让我们回到应用于页面的Angular控制器中。我们在过一下$scope和$http。

$scope:控制器和视图层之间的粘合剂。基本上,变量使用$scope从我们的控制器和视图层之间传递和往来。具体详细的定义,请参见文档。

$http:Angular服务来帮助我们处理POST请求。更多信息,请参见文档。

使用数据绑定获取变量

好了,闲话少说。我们将这些讨论应用到表单中去。方法比上面讨论的要简单。我们想Angular控制器和视图中分别添加一行。

<!-- index.html -->

...

 <!-- PROCESS FORM WITH AJAX (NEW) -->
 <script>

  // define angular module/app
  var formApp = angular.module('formApp', []);

  // create angular controller and pass in $scope and $http
  function formController($scope, $http) {

   // create a blank object to hold our form information
   // $scope will allow this to pass between controller and view
   $scope.formData = {};

  }

...

现在,我们已经建立了一个formData对象。让我们用表单数据来填充它。在显示调用每个输入和获得val()之前,我们用ng-model绑定一个特殊的输入到变量。

<!-- index.html -->

...

 <!-- FORM -->
 <form>
  <!-- NAME -->
  <div id="name-group" class="form-group">
   <label>Name</label>
   <input type="text" name="name" class="form-control" placeholder="Bruce Wayne" ng-model="formData.name">
   <span class="help-block"></span>
  </div>

  <!-- SUPERHERO NAME -->
  <div id="superhero-group" class="form-group">
   <label>Superhero Alias</label>
   <input type="text" name="superheroAlias" class="form-control" placeholder="Caped Crusader" ng-model="formData.superheroAlias">
   <span class="help-block"></span>
  </div>

  <!-- SUBMIT BUTTON -->
  <button type="submit" class="btn btn-success btn-lg btn-block">
   <span class="glyphicon glyphicon-flash"></span> Submit!
  </button>
 </form>

 <!-- SHOW DATA FROM INPUTS AS THEY ARE BEING TYPED -->
 <pre>
  {{ formData }}
 </pre>

...

现在,既然Angular已经将每个输入绑到了formData。 当你输入每个输入框,你可以看到formData对象被填充了!有没有很酷!

你不必在view中使用$scope。一切被认为是嵌入到$scope中的。
 
处理表单

在我们的旧表单中,我们使用jQuery提交表单,像这样$('form').submit()。现在我们使用Angular称作ng-submit的特性。要想完成这个,我们需要添加一个控制器函数来处理表单,然后告诉我们form使用这个控制器函数:

<!-- index.html -->

...

 <!-- PROCESS FORM WITH AJAX (NEW) -->
 <script>

  // define angular module/app
  var formApp = angular.module('formApp', []);

  // create angular controller and pass in $scope and $http
  function formController($scope, $http) {

   // create a blank object to hold our form information
   // $scope will allow this to pass between controller and view
   $scope.formData = {};

   // process the form
   $scope.processForm = function() {

   };

  }

...

 <!-- FORM -->
 <form ng-submit="processForm()">

...

现在我们的form知道提交时使用控制器函数了。既然已经到位了,然我们用$http来处理表单吧。

处理表单的语法看起来跟原始方式很像。好处是我们不需要手动抓取表单数据,或者注入,隐藏,添加类显示错误或成功信息。

<!-- index.html -->

...

// process the form
$scope.processForm = function() {
 $http({
  method : 'POST',
  url  : 'process.php',
  data : $.param($scope.formData), // pass in data as strings
  headers : { 'Content-Type': 'application/x-www-form-urlencoded' } // set the headers so angular passing info as form data (not request payload)
 })
  .success(function(data) {
   console.log(data);

   if (!data.success) {
    // if not successful, bind errors to error variables
    $scope.errorName = data.errors.name;
    $scope.errorSuperhero = data.errors.superheroAlias;
   } else {
    // if successful, bind success message to message
    $scope.message = data.message;
   }
  });
};

...

这就是我们的表单!没有添加或移除类。我们需要每次提交表单时都清楚错误。我们只需绑定变量和需要用到的视图。这非常棒,因为处理器用来处理数据,而视图用来显示数据.

jQuery POST vs Angular POST

有时能看到用POST方式提交在服务器中看不到数据,这是因为jQuery和Angular的序列化和发送数据的方式不同。这归结于你所使用的服务器语言和它理解Angular提交的数据的能力。

上面的代码是应用于PHP服务器的,jQuery对于$.param函数则是必需的。虽然实现上文中提到的内容有非常多不使用jQuery的方法,但在本实例中,使用jQuery的唯一原因就是,它更简单。

下面简洁的语法将会基于你服务器端语言来工作。

简洁语法

这个例子是以字符串的方式发送数据,并且发送你的头信息。如果你不需要这些,并且希望Angular 的$http POST尽可能的简洁,我们可以使用简写方法:

...
 $http.post('process.php', $scope.formData)
  .success(function(data) {
   ...
  });
...

绝对更简洁更容易记住方法。

$http 内部控制器: 理想的,你可以将$http请求从controller移除到 service.这只是为了演示目的,我们将会尽快在service上进行讨论.

在视图中显示错误和信息

我们将使用指令ng-show和ng-class来处理我们的视图,Angular双方括号允许我们将变量放置在我们需要的地方。

  • ng-show: 根据变量值是否存在来显示或隐藏元素. 文档
  • ng-class: 根据变量值是否存在(或一些其他表达式)来添加或移除类. 文档
<!-- index.html -->

...

 <!-- SHOW ERROR/SUCCESS MESSAGES -->
 <div id="messages" ng-show="message">{{ message }}</div>

 <!-- FORM -->
 <form>
  <!-- NAME -->
  <div id="name-group" class="form-group" ng-class="{ 'has-error' : errorName }">
   <label>Name</label>
   <input type="text" name="name" class="form-control" placeholder="Bruce Wayne">
   <span class="help-block" ng-show="errorName">{{ errorName }}</span>
  </div>

  <!-- SUPERHERO NAME -->
  <div id="superhero-group" class="form-group" ng-class="{ 'has-error' : errorSuperhero }">
   <label>Superhero Alias</label>
   <input type="text" name="superheroAlias" class="form-control" placeholder="Caped Crusader">
   <span class="help-block" ng-show="errorSuperhero">{{ errorSuperhero }}</span>
  </div>

...

我们的表单完成了!通过强大的Angular,我们可以将这些愚蠢的显示/隐藏的js代码逻辑从视图中移走 了。现在我们的js文件只用来处理数据,并且视图可以做它自己的事情了。

我们的类和错误/成功等提示信息将在可获取时显示而不可获取时隐藏。当我们无须再像使用老的javascript那样担心是否已经考虑全面,这变得更加容易。你也无须再担心是否记得隐藏每处form提交时的那些错误信息。

Angular表单验证 获取更多表单验证的信息,请研读我们另一文章:AngularJS Form Validation。
结束语

现在我们已把美观的表单全部转变为Angular的了。我们共同学习了许多概念,希望你与它们接触更多,它们也将更易用。

回顾:

  • 创建一个Angular module
  • 创建一个Angular controller
  • 双向数据绑定
  • ng-model绑定inputs
  • ng-click提交表单
  • 使用双向数据绑定展示表单错误
  • 展示一个基于是否变量存在的div
  • 添加一个基于是否变量存在的类

这些Angular技术将在更庞大的应用中使用,你可以用它们创建许多好东西。祝Angular之途愉快,敬请期待更多深入的文章。同时,你也可以通过深入了解其指南,服务和厂商等来继续学习Angular。

(0)

相关推荐

  • AngularJS自动表单验证

    AngularJS的另外一种表单验证方式是自动验证,即通过directive来实现,除了AngularJS自带的directive,还需要用到angular-auto-validate这个第三方module. 有关angular-auto-validate: 安装:npm i angular-auto-validate 引用:<script src="../node_modules/angular-auto-validate/dist/jcs-auto-validate.min.js&qu

  • AngularJS中实现用户访问的身份认证和表单验证功能

    身份验证 权限的设计中比较常见的就是RBAC基于角色的访问控制,基本思想是,对系统操作的各种权限不是直接授予具体的用户,而是在用户集合与权限集合之间建立一个角色集合.每一种角色对应一组相应的权限.     一旦用户被分配了适当的角色后,该用户就拥有此角色的所有操作权限.这样做的好处是,不必在每次创建用户时都进行分配权限的操作,只要分配用户相应的角色即可,而且角色的权限变更比用户的权限变更要少得多,这样将简化用户的权限管理,减少系统的开销. 在Angular构建的单页面应用中,要实现这样的架构我们

  • AngularJS使用指令增强标准表单元素功能

    Angular 可使用指令无缝地增强标准表单元素的功能,我们将讨论它的优点,包括: 数据绑定.建立模型属性.验证表单.验证表单后反馈信息.表单指令属性 下面我们通过案例验证他们的用法: 一.双向数据绑定(ng-model)和建立模型属性 <!DOCTYPE> <!-- use module --> <html ng-app="exampleApp"> <head> <title>Angular Directive</ti

  • 详解AngularJS实现表单验证

    开始学习AngularJS表单验证: 常用的表单验证指令 1. 必填项验证 某个表单输入是否已填写,只要在输入字段元素上添加HTML5标记required即可: 复制代码 代码如下: <<input type="text" required /> 2. 最小长度 验证表单输入的文本长度是否大于某个最小值,在输入字段上使用指令ng-minleng= "{number}": 复制代码 代码如下: <<input type="tex

  • angularjs $http实现form表单提交示例

    需求:请求第三方后台接口返回一段html字符串如下,由前端去实现form表单的POST提交, 说明:form表单submit()实现自动提交input标签hidden,注意script代码中的document.redirect.submit(); <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> </head

  • AngularJS表单编辑提交功能实例

    研究了下高大上的AngularJS决定试试它的表单编辑提交功能,据说比JQuery强的不是一星半点. 好奇呀,试试吧.....搞了好久,尼玛...靠..靠..靠..尼玛 ..靠..靠....好吧,谁让我手欠呢. 搜索到了很多关于AngularJS Form的案例 如: http://www.angularjs.cn/A08j https://github.com/tiw/angularjs-tutorial https://github.com/tiw/angularjs-tutorial/bl

  • AngularJS实现表单元素值绑定操作示例

    本文实例讲述了AngularJS实现表单元素值绑定操作.分享给大家供大家参考,具体如下: ng-disabled:绑定控件的disabled属性 ng-show:显示或者隐藏元素:ms-visible ng-hide:和ng-show的功能恰好相反 css内容: div.d1{ width: 20px; height: 20px; background-color: pink; } div.d2{ width: 20px; height: 20px; background-color: blac

  • AngularJS手动表单验证

    所谓手动验证是通过AngularJS表单的属性来验证,而成为AngularJS表单必须满足两个条件: 1.给form元素加上novalidate="novalidate": 2.给form元素加上name="theForm", 如下: <!DOCTYPE html> <html lang="en" ng-app="myApp1"> <head> <meta charset="

  • AngularJS的表单使用详解

    AngularJS提供丰富填写表单和验证.我们可以用ng-click来处理AngularJS点击按钮事件,然后使用 $dirty 和 $invalid标志做验证的方式.使用novalidate表单声明禁止任何浏览器特定的验证.表单控件使用了大量的角活动.让我们快速浏览一下有关事件先. 事件 AngularJS提供可与HTML控件相关联的多个事件.例如ng-click通常与按钮相关联.以下是AngularJS支持的事件. ng-click ng-dbl-click ng-mousedown ng-

  • AngularJS实现表单验证

    虽然我不是前端程序员,但明白前端做好验证是多么重要. 因为这样后端就可以多喘口气了,而且相比后端什么的果然还是前端可以提高用户的幸福感. AngularJS提供了很方便的表单验证功能,在此记录一番. 首先从下面这段代码开始 复制代码 代码如下: <form ng-app="myApp" ng-controller="validationController" name="mainForm" novalidate>     <p&

  • AngularJS使用ngMessages进行表单验证

    AngularJS 诞生于2009年,由Misko Hevery 等人创建,后为Google所收购.是一款优秀的前端JS框架,已经被用于Google的多款产品当中.AngularJS有着诸多特性,最为核心的是:MVVM.模块化.自动化双向数据绑定.语义化标签.依赖注入等等. 名称为"ngMessages"的module,通过npm install angular-messages进行安装.在没有使用ngMessages之前,我们可能这样写验证: <form name="

随机推荐