我们会关注两种提交表单的方式:
旧方法:jQuery和PHP提交表单
新方法:AngularJS和PHP提交表单
首先看一下我们的表单,超级简单:
形式要求
实现页面无刷新表单处理
输入姓名和超级英雄别名
如果有错误,显示错误提示
如果输入有误,将输入变成红色
如果所有内容ok,显示成功提示
文档结构
在我们的展示中,仅需两个文件
index.html
process.php
表单处理
让我们新建一个PHP来处理表单。该页面非常小并且使用POST方式提交数据。
处理表单:这对我们来说并不是那么重要的。你可以使用其他你喜欢的语言来处理你的表单。
// process.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来展示我们的表单
Angular Forms
Submitting Forms with Angular
Name
Superhero Alias
Submit!
现在,我们有了表单。我们另外还使用了Bootstrap来使表单看起来不是那么丑。使用Bootstrap语法规则,每个input下含有一个spot来展示我们文本的错误信息。
使用jQuery提交表单
现在,让我们来使用jQuery处理表单提交。我会将所有的代码添加到空的
...
$(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('
' + data.message + '
');
}
}
});
// stop the form from submitting and refreshing
event.preventDefault();
});
});
...
这里处理表单有不少的代码。我们有获取表单中变量的代码,有使用AJAX将数据发送至我们的表单的代码,有检查是否有错和显示成功提示的代码。除此之外,我们希望每次表单提交之后,过去的错误信息都会被清除。确实是不少代码。
现在,如果表单中含有错误,则:
如果提交成功:
现在,让我们看使用Angular来提交相同的表单。记住,我们不需要更改任何关于我们的PHP如何处理表单的内容,我们的应用依然会具备相同的功能(在同一个地方展示错误和成功信息)。
使用Angular提交表单
我们准备在之前使用的
设置一个Angular应用
步骤为:
1. 加载Angular
2. 设置module
3. 这是controller
4. 将module和controller应用于HTML
5. 设置双向变量绑定
6. 这是错误和信息
看起来好像是很多内容,但是最终,我们会用非常少的代码,并且看起来会非常简洁。另外,创建带有更多输入更大的表单,也会更容易。
Angular 组件和控制器
首先,加载Angular并且新建组件和控制器
...
// define angular module/app
var formApp = angular.module('formApp', []);
// create angular controller and pass in $scope and $http
function formController($scope, $http) {
}
...
现在,我们有了Angular应用的基础。我们已经加载了Angular,创建了组件模块和控制器,并且将其应用于我们的网站。
接下来,我将展示双向绑定是如何工作的。
双向数据绑定
这是Angular的核心思想之一,也是功能最强大的内容之一。在Angular文档中,我们看到:“在Angular网页应用中的数据绑定,是模型和视图层之间的数据自动同步。”这意味着,我们需要在表单中抓取数据,使用$('input[name=name]').val()并不是必需的。
我们在Angular中将数据和变量绑定在一起,无论是javascript也好,view也罢,只要有改变,两者皆变。
为了演示数据绑定,我们需要获取表单的input来自动填充变量formData。让我们回到应用于页面的Angular控制器中。我们在过一下$scope和$http。
$scope:控制器和视图层之间的粘合剂。基本上,变量使用$scope从我们的控制器和视图层之间传递和往来。具体详细的定义,请参见文档。
$http:Angular服务来帮助我们处理POST请求。更多信息,请参见文档。
使用数据绑定获取变量
好了,闲话少说。我们将这些讨论应用到表单中去。方法比上面讨论的要简单。我们想Angular控制器和视图中分别添加一行。
...
// 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绑定一个特殊的输入到变量。
...
Name
Superhero Alias
Submit!
{{ formData }}
...
现在,既然Angular已经将每个输入绑到了formData。 当你输入每个输入框,你可以看到formData对象被填充了!有没有很酷!
你不必在view中使用$scope。一切被认为是嵌入到$scope中的。
处理表单
在我们的旧表单中,我们使用jQuery提交表单,像这样$('form').submit()。现在我们使用Angular称作ng-submit的特性。要想完成这个,我们需要添加一个控制器函数来处理表单,然后告诉我们form使用这个控制器函数:
...
// 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知道提交时使用控制器函数了。既然已经到位了,然我们用$http来处理表单吧。
处理表单的语法看起来跟原始方式很像。好处是我们不需要手动抓取表单数据,或者注入,隐藏,添加类显示错误或成功信息。
...
// 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的唯一原因就是,它更简单。