文章目录
  1. 1. 有关angularJS$http和$q
    1. 1.1. $http
    2. 1.2. Promise对象
    3. 1.3. 在AngularJS中使用Promise: $q
    4. 1.4. 编写一个集成$q服务
    5. 1.5. 参考
  2. 2. 异步提交带图片的表单
    1. 2.1. XMLHttpRequest Level 2
    2. 2.2. FormData对象
    3. 2.3. File API
    4. 2.4. 编写异步提交带图片表单的服务
    5. 2.5. 使用异步提交带图片表单的服务
  3. 3. 结束语

最近的一个项目使用AngularJS(v1.2.6)作为前端的框架,《Angular使用笔记》系列用于记录过程中的一些使用和解决方法。
本文记录编写异步提交带图片的表单服务的过程,同时简单介绍$q服务,以及HTML5 File API和FormData。

有关angularJS$http和$q


$http

  • $http是一个用于读取web服务器上数据的服务
  • $http.get()从web服务器上读取静态JSON数据
  • $http的post使用会与ajax不一样哦,需要设置Content-Type值,具体可以查看《Angular使用笔记2–创建登录页面》里的解决办法

Promise对象

Javascript采用回调函数(callback)来处理异步编程。从同步编程到异步回调编程有一个适应的过程,但是如果出现多层回调嵌套,也就是我们常说的厄运的回调金字塔(Pyramid of Doom)。

  • Promise是一种异步方式处理值(或者非值)的方法
  • Promise允许以一种同步的方式编写异步代码
  • 代表了一个函数最终可能的返回值或者抛出的异常
  • Promises/A规范
    • promise有三种状态:未完成(unfulfilled),完成(fulfilled) 和失败(failed)
    • promise的状态只能由未完成转换成完成,或者未完成转换成失败
    • promise的状态转换只发生一次

在AngularJS中使用Promise: $q

$q是Angular的一种内置服务,它可以使你异步地执行函数,并且当函数执行完成时它允许你使用函数的返回值(或异常)

  • $q常用的几个方法

    • defer() 创建一个deferred对象,这个对象可以执行几个常用的方法,比如resolve,reject,notify等
    • all() 传入Promise的数组,批量执行,返回一个promise对象
    • when() 传入一个不确定的参数,如果符合Promise标准,就返回一个promise对象
  • defer()方法

    • 在$q中,可以使用resolve方法,变成完成状态;使用reject方法,变成拒绝状态
    • defer()用于创建一个deferred对象,defer.promise用于返回一个promise对象,来定义then方法
    • then中有三个参数,分别是成功回调、失败回调、状态变更回调
  • all()方法

    • 可以把多个primise的数组合并成一个
    • 当所有的promise执行成功后,会执行后面的回调
  • when()方法

    • 可以传入一个参数,这个参数可能是一个值,可能是一个符合promise标准的外部对象

编写一个集成$q服务

这里我们将单个$q服务和多个$q服务(all()方法)集成成一个服务,返回Promise

  • query方法
    • query方法返回一个对象,对象包括单个$http请求的Promise以及取消请求的方法
    • multiquery方法返回多个$http请求的promise
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
app.factory('qService', ['$http', '$q', function($http, $q) {
return {
query: function(param) {
var deferred = $q.defer(), //声明承诺
cancel = function(reason) { //取消promise事件
deferred.reject(reason);
};
$http(param).
success(function(data) {
deferred.resolve(data); //请求成功
}).
error(function(data) {
deferred.reject(data); //请求失败
});
return {
promise: deferred.promise, // 返回承诺
cancel: cancel // 返回取消事件
};
},
multiquery: function(params) {
var promises = [];
for (var i in params) {
var promise = $http(params[i]); //返回$http服务
promises.push(promise); //将$http服务添加进队列
}
return $q.all(promises); //返回Promise承诺
}
};
}])

注意:

  • 这里取消promise的事件只适合GET请求,若在POST请求上请求可能会导致不可预测的错误哦
  • 多个http服务的请求的错误回调本骚年还没想到解决办法,请小伙伴们多多赐教

参考

异步提交带图片的表单


在Angular中要实现异步提交图片,可以使用组件或者利用HTML5属性formdata和fileapi自己实现图片的提交哦。

  • Angular的组件或者服务本骚年木有找到…
  • 既然已经使用了jQuery,推荐一个异步提交表单的插件jQuery.form

XMLHttpRequest Level 2

  • XMLHttpRequest是一个浏览器接口,使得Javascript可以进行HTTP(S)通信
  • 新版本的XMLHttpRequest对象(XMLHttpRequest Level 2)功能
    • 1.可以设置HTTP请求的时限
    • 2.可以使用FormData对象管理表单数据
    • 3.可以上传文件
    • 4.可以请求不同域名下的数据(跨域资源共享,Cross-origin resource sharing,简称CORS)
    • 5.可以获取服务器端的二进制数据
    • 6.可以获得数据传输的进度信息

这里主要使用FromData,具体其他请查看《触碰jQuery:AJAX异步详解》

FormData对象

HTML5新增了一个FormData对象,可以模拟表单
使用方法如下:

1
2
3
4
5
6
7
8
9
10
window.FormData //检测兼容性
var formData = new FormData(); //新建FormData对象
formData.append(name, value); //添加表单项
xhr.send(formData); //发送FormData对象
//以下方法可直接获取网页表单的值
var form = document.getElementById('form'); //获取form对象
var formData = new FormData(form); //生成FormData对象
formData.append(name, value); // 添加表单项
xhr.open('POST', form.action);
xhr.send(formData);//发送FormData对象

File API

HTML5提供了File API,允许js读取本地文件。主要用于本地预览图片。

  • FileList接口: 可以用来代表一组文件的JS对象,比如用户通过input[type=”file”]元素选中的本地文件列表
  • Blob接口: 用来代表一段二进制数据,并且允许我们通过JS对其数据以字节为单位进行“切割”
  • File接口: 用来代步一个文件,是从Blob接口继承而来的,并在此基础上增加了诸如文件名、MIME类型之类的特性
  • FileReader接口: 提供读取文件的方法和事件
  • 检查File API兼容性: window.File&&window.FileReader&&window.FileList&&window.Blob

其他方法可参考《HTML 5中的文件处理之FileAPI》

编写异步提交带图片表单的服务

现在我们利用FormData和FileAPI,可以开始编写异步提交带图片表单的服务了。
添加工厂服务,代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
/* params:
* {
* fileinput: 传入file input的dom对象,
* url: 服务器地址,
* other: 其他需要发送的参数{键:值}
* callback: 成功回调
* errback: 失败回调
* }
*/
.factory('AsyncForm', function() {
var feature = {}; //用于检查FormData和fileAPI的兼容性
feature.fileapi = (window.File && window.FileReader && window.FileList && window.Blob);
feature.formdata = window.FormData !== undefined;
var fileAPI = feature.fileapi && feature.formdata,
formData,
xhr = window.XMLHttpRequest ? new XMLHttpRequest() : new ActiveXObject('Microsoft.XMLHTTP'),
AsyncForm = function(params) {
if (fileAPI) {
var otherparams = params.other, //其他需要发送的参数{键:值}
callback = params.callback, //成功回调
errback = params.errback, //失败回调
files = (params.fileinput && params.fileinput.files) ? params.fileinput.files : {}, //传入file input的dom对象
onreadystatechange;
//设置onreadystatechange
onreadystatechange = function(func, _xhr, errfunc) {
_xhr.onreadystatechange = function() {
if (_xhr.readyState == 4) {
if (_xhr.status == 200) {
//判断若有成功回调,则执行
if (typeof func == 'function') {func(_xhr.responseText);}
} else {
//判断若有失败回调,则执行
if (typeof errfunc == 'function') {errfunc();}
}
}
}
};
//新建formData对象
formData = new FormData();
//判断是否有图片对象,有则添加进队列
if (files) {
for (var i = 0; i < files.length; i++) {
formData.append('file', files[i]);
}
}
//若有其他表单项,添加进队列
for (i in otherparams) {
formData.append(i, otherparams[i]);
}
//设置POST方法,以及服务器地址
xhr.open('post', params.url);
onreadystatechange(callback, xhr, errback);
} else {
alert("浏览器不支持FormData或fileAPI");
}
};
AsyncForm.prototype = {
//提交表单事件
submit: function() {
xhr.send(formData);
},
};
return AsyncForm;
});

  • 这里的fileinput参数传入file input的dom对象,其实可以直接传入file的,大家可以进行优化哦。

使用异步提交带图片表单的服务

  • 在控制器中需注入依赖AsyncForm
1
2
3
4
5
6
7
8
9
10
11
12
13
//创建表单
var asform = new AsyncForm({
fileinput: $input, //传入file input的dom对象
url: url, //服务器地址
other: { //其他需要发送的参数{键:值}
name: value,
name: value,
},
callback: function(data) {}, //成功回调
errback: function() {} //失败回调
});
//提交表单
asform.submit();

结束语


这里没有考虑不支持HTML5时候的处理办法,大家可以私底下试试哦,提示:)可使用iframe实现哦。
此处查看项目代码(仅包含app部分)

查看Github有更多内容噢:https://github.com/godbasin
更欢迎来被删的前端游乐场边撸猫边学前端噢

码生艰难,写文不易,给我家猪囤点猫粮了喵~

作者:被删

出处:https://godbasin.github.io

本文版权归作者所有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。

文章目录
  1. 1. 有关angularJS$http和$q
    1. 1.1. $http
    2. 1.2. Promise对象
    3. 1.3. 在AngularJS中使用Promise: $q
    4. 1.4. 编写一个集成$q服务
    5. 1.5. 参考
  2. 2. 异步提交带图片的表单
    1. 2.1. XMLHttpRequest Level 2
    2. 2.2. FormData对象
    3. 2.3. File API
    4. 2.4. 编写异步提交带图片表单的服务
    5. 2.5. 使用异步提交带图片表单的服务
  3. 3. 结束语