文件select和drop
使用插件则ngf-select
或 ngf-drop
必须强制使用一个.
ngf-select
选择相关的其它指令,一般使用*
作为前缀
ngf-drop
拖放相关的其它指令,一般使用+
作为前缀
具体使用
// 使用标签可以为下面3个中的任意1个
<div|button|input type="file"|ngf-select|ngf-drop>
</div|button|input>
1.标签中的属性
#1
ngf-select="" 或者 ngf-select="upload($files, ...)" // 方法当文件选中或被清除时被调用
ngf-drop="" 或者 ngf-drop="upload($files, ...)" // 当文件被放置的时候方法被调用
可以使用 ng-model
或者 ngf-change
来代替下面函数中的参数
#2
ngf-change="upload($files, $file, $newFiles, $duplicateFiles, $invalidFiles, $event)" // 当文件被选中,放置或清除时方法调用
ng-model="myFiles" // 绑定有效选择或放置的文件到作用域模型, 可以是数组或字符串, 这个由 `ngf-multiple` 和 `ngf-keep`值决定
#3
// updateOn 用于禁用点击重置或粘贴更新,浏览器图片放置等
// allowInvalid 默认值为false, 允许模型(model)中存在无效文件
// debounce 用于延时模型更新(单位为ms)
ng-model-options="{updateOn: 'change click drop dropUrl paste', allowInvalid: false, debounce: 0}"
// 将无效选择的文件或放置文件绑定到模型上
ng-model-invalid="invalidFile(s)"
// 在模型改变, 验证和resize之前,在文件被选择或放置之后被调用
ngf-before-model-change="beforeChange($files, ...)"
#4
// 禁用这个元素
ng-disabled="boolean"
// 默认值为false, 对这个元素禁止选择/放置文件
ngf-select-disabled="boolean"
ngf-drop-disabled="boolean"
// 默认值为false,是否允许选择多个文件
ngf-multiple="boolean"
// 默认值为false, 是否保留先前模型中的文件和后面添加的新文件
// 'distinct' 移除重复的文件, '$newFile', '$duplicateFiles' 在 ngf-change/select/drop 函数中设置
ngf-keep="true|false|'distinct'"
#5
// 默认值为false, 用于旋转包含 exif orientation数据的jpeg图片文件
ngf-fix-orientation="boolean"
#6
// 允许移动设备通过相机来添加图片
*ngf-capture="'camera'" 或者 *ngf-capture="'other'"
// 标准HTML接收的属性,浏览器选择时弹出窗口
*ngf-accept="'image/*'"
// 默认值为true, 允许放置文件,只针对chrome webkit 浏览器
+ngf-allow-dir="boolean"
// 默认值为false,在文件放置数据中包含路径
+ngf-include-dir="boolean"
#7
// 默认值为 'dragover', 拖动时添加css class, 可以是一个字符串,或一个函数返回类名或json对象
// 'accept/reject' class 只用于在chrome
+ngf-drag-over-class="{pattern: 'image/*', accept: 'acceptClass', reject: 'rejectClass', delay: 100}"
或者 "'myDragOverClass'"
或者 "'calcDragOverClass($event)'"
// 依据浏览器是否支持文件drag&drop来设置作用域的值为true或者false
+ngf-drop-available="dropSupported"
// 默认值为false, 是否冒泡 拖拽事件
+ngf-stop-propagation="boolean"
// 默认值为false, 隐藏元素。如果文件拖拽不存在
+ngf-hide-on-drop-not-avaliable="boolean"
#8
ngf-resize="{width: 100, height: 100, quality: .8, type="image/jpeg",
ratio: '1:2', centerCrop: true, pattern=".jpg", restoreExif: false
}"
// 或者
// 函数返回一个promise
// resolve则获取选项: resize图片大小为给定的宽高或ratio; quality为可选的,范围为0.1-1.0
// type: 可选,转换为指定的图片格式
// centerCrop: 默认值为false, 不对图片进行裁剪,将适应给定的宽高或比率; 设置为true将不适应给定宽高的图片进行裁剪,可能导致图片宽或高小于给定的宽或高
// pattern:只对名字或类型相匹配的文件进行resize, 和'ngf-pattern'类似
// restoreExif: 默认值为true, 将修复resize 图片的exif信息
ngf-resize="resizeOptions()"
// 只用这个函数返回为true才使用 'ngf-resize'属性
ngf-resize-if="$width > 1000 || $height > 1000"
或者 "resizeCondition($file, $width, $height)"
// 默认值为false, 如果设置为true,则所有验证将在图片被rezise之后进行,因此在resize之前的验证错误将会被忽略
ngf-validate-after-resize="boolean"
#9
验证
// 允许选择或放置的最大文件数量,验证错误名: maxFiles
ngf-max-files="10"
// 允许选择文件类型,逗号分割用于过滤文件名和类型
// 排除不允许的文件类型使用 '!', 验证错误名: pattern
ngf-pattern="'.pdf,.jpg,video/*, !.jop'"
// 文件大小的验证
ngf-min-size
ngf-max-size
ngf-max-total-size = "100"(单位为bytes) 或者 "'10KB'" 或者 "'10MB'" 或者 "'10GB'"
// 对图片尺寸进行验证
ngf-min-height
ngf-max-height
ngf-min-weight
ngf-max-weight = "1000"(单位 px)
ngf-ratio="8:10, 1.6" // 指定的image ratio格式
ngf-dimensions="$width > 1000 || $height > 1000"
"validateDimension($file, $width, $height)"
// 对视频或音频文件进行验证
ngf-min-duration
ngf-max-duration= "100.5"(单位 s) 或者 "'10s'" 或者 "'10m'" 或者 "'10h'"
ngf-duration="$duration > 1000"
"validateDuration($file, $duration)"
// 上面所有验证的简写
ngf-validate="{size: {min: 10, max: '20MB'},
width: {min: 100, max: 10000},
height: {min: 100, max: 300},
ratio: '2x1',
duration: {min: '10s', max: '5m'},
pattern: '.jpg'
}"
// 自定义验证函数,返回布尔值或包含错误的string
ngf-validate-fn="validate($file)"
// 自定义验证函数,返回一个promise
ngf-validate-async-fn="validate($file)"
// 默认值为false,如果设置为true, 'file.$error' 将被设置
// 例如图片加载错误或浏览器不支持的视频
// 默认情况会将设文件是有效的,如果浏览器不能计算出duration或dimension
ngf-validate-force="boolean"
// 忽略指定验证类型的错误
ngf-ignore-invalid="'pattern maxSize'"
#10
其它
<div|input|button ngf-no-file-drop>文件拖拽不支持</div|...>
// 将文件转换为base64 data url
<a href="file | ngfDataUrl">image</a>
2.文件预览
使用方式:
<img|audio|video|div
// 属性
>
可选属性有:
// 预览选择的文件,设置src属性为文件的data url
*ngf-src="file"
// 给文件设置背景图片样式
*ngf-background="file"
// 在设置为src或背景图片前resize 图片(只对图片有效)
ngf-resize="{width: 20, height: 20, quality: 0.9}"
// 强制base64 url代替对象url, 默认值为false
ngf-no-object-url="true or false"
另外对图片:
<div|span|...
*ngf-thumbnail="file" // 产生图片文件的缩略图
ngf-size="{width: 20, height: 20, quality: 0.9}" // 图片将缩放为这个尺寸
ngf-as-background="boolean" // 如果为true,则设置为背景图片而不是src属性
>
3.上传服务 Upload service
var upload = Upload.upload({
// 配置信息
})
配置信息
#1 上传地址
*url: 'server/upload/url', // 可以为 upload.php脚本,node.js路由, 或者 servlet url
#2 上传数据
*data: {key: file, otherInfo: uploadInfo}
// 指定文件和发送到服务器的可选数据,每个包含嵌套对象的字段将以 'form data multipart' 形式发送
// 示例
{pic: file, username: username}
{files: files, otherInfo: {id: id, person: person, ...}}
{profiles: {
[
{pic: file1, username: username1},
{pic: file2, username: username2}
] // 嵌套数据包含多个文件(html5)
}}
{file: file, info: Upload.json({id: id, name: name, ...})} // 将字段以json字符串格式发送
{picFile: Upload.rename(file: 'profile.jpg'), title:tile}
#3 请求方式
method: 'POST'(默认值) || 'PUT'(HTML5)
#4 头文件
headers: {'Authorization': 'xxx'} // (HTML5)
#5 是否带有凭证
withCredentials: boolean
#6 可恢复上传(HTML5)
resumeSizeUrl: '/upload/size/url?file=' + file.name // 目前上传到服务器文件的大小
resumeSizeResponseReader: function(data) {return data.size;} // 读取上传的文件大小从 resumeSizeUrl GET response中
resumeSize: function() {return promise;} // 返回一个promise,用于计算上传到服务器文件的大小
resumeChunkSize: 1000 || '10KB' || '10MB' // 以块上传指定的文件大小
#7 是否取消进度条
disableProgress: boolean // 默认值为false
#8 其它 angular '$http()' 选项可以这这里使用
上面的 var upload
是一个promise,有如下的一些方法
upload.then(function(resp) {
// 文件上传成功
console.log('file ' + resp.config.data.file.name + 'is uploaded successfully. Response: ' + resp.data);
}, function(resp) {
// 处理错误
}, function(evt) {
// 进度通知
console.log('progress: ' + parseInt(100.0 * evt.loaded / evt.total) + '% file : ' + evt.config.data.file.name);
});
// 捕获异常
upload.catch(errorCallback)
upload.finally(callback, notifyCallback);
// 访问底层XMLHttpRequest或者添加事件listeners
upload.xhr(function(xhr) {
xhr.upload.addEventListener(...)
});
// 取消或终止上传过程
其它的上传方式和其它操作
发送文件二进制文件的content-type, 可用于将文件上传到CouchDB, imgur等,html5 FileReader接口是必要的, 这相当于angular $http(),但是允许你html5浏览器的progress事件进行监听
Upload.http({
url: '/server/upload/url',
headers: {
'Content-Type': file.type
},
data: file
})
// 给ngf-select, ngf-drop指令设置默认值
Upload.setDefaults({ngfMinSize: 2000, ngfMaxSize: 200000, ....0})
// 转换单个文件或数组文件为base64 data url形式的单个或数组文件
// 用于在json内部以base64格式发送给数据库
Upload.base64DataUrl(files).then(function(urls){...})
// 将文件转换为二进制url对象或者base64数据url 依据 'disallowObjectUrl' 值
Upload.dataUrl(file, boolean).then(function(url) {...});
// 获取图片文件的围度
Upload.imageDimensions(file).then(function(dimensions){console.log(dimensions.width, dimensions.height);});
// 获取 audio/video 时长
Upload.mediaDuration(file).then(function(durationInSeconds){...});
// 修改图片尺寸, 返回一个promiase
// 选项 width, height, quality, type, radio, centerCrop, resizeIf, restoreExif
// resizeIf(width, height) 返回布尔值
Upload.resize(file, options).then(function(resizeFile){...})
// 返回布尔值,是否浏览器支持图片尺寸缩放
Upload.isResizeSupported()
// 是否浏览器支持可继续上传,返回布尔值
Upload.isResumeSupported()
// 给上传文件重命名
Upload.rename(file, newName)
// 将对象转换为application/json文件类型的二进制对象(HTML5)
Upload.jsonBlob(obj)
// 和angular.toJson(obj)一样
Upload.json(obj)
// 如果正在上传则返回true
Upload.isUploadInProgress()
// 检查对象是否为文件,可用于 Upload.upload()/http() 中
Upload.isFile(obj)
4.注意事项
ng-model
ng-model
的值将为单一文件而不是数组,如果全部满足下列情况:
-
ngf-multiple
没有设置或设置为false -
multiple
: 没有设置该属性 -
ngf-keep
: 没有设置或设置为false
validation
当表单中指定的任何验证指令生效,我们可以通过 myForm.myFileInputName.$error.<validate error name>
使用验证值, 例如 form.file.$error.pattern
.如果允许选择多个文件,可以指定 ngf-model-invalid="invalidFiles"
,将无效文件赋给模型,通过 file.$error
找到错误和file.$errorParam
找到错误描述。可以使用angular的 ngf-model-option="{allowInvalidL: true}"
允许给ng-model设置无效文件
上传多个文件
只对 HTML5 FormData浏览器(非IE8-9), 有一个数组的文件或超过一个文件在 data
以一个请求发送他们。非html5浏览器由于falsh限制,只能一次请求上传一个文件。可以迭代文件,一个一个的上传文件
Upload.setDefaults(options)
: 如果有多个文件选择或拖拽,可以给它们设置默认值。 options是一个json对象,使用camalCase命名
拖拽样式
对于文件拖拽, ngf-drag-over-class
能够用于给drop区域添加样式。可以是一个依据$event
返回class name的函数。 默认是 dragover
字符串。只有chrome可以是一个json对象 {accept: 'a', 'reject': 'r', pattern: 'image/*', delay: 10}
5.老浏览器
对于不支持HTML5 FormData(IE8, IE9)的浏览器,将会使用 FileAPI
模块。注意需要在浏览器中安装flash,因为FileAPI
需要使用Flash上传文件。
有2个文件: FileAPI.min.js
, FileAPI.flash.swf
将被模块按需加载(如果浏览器支持html5表单数据就没必要包含在html中)。可以将这2个文件放在服务器angular-file-upload-shim(.min).js
旁,自动的从相同的路径加载或者指定这些文件所在的路径,如果他们在不同的路径下:
<script>
// 在 angular-file-upload-shim(.min).js之前被加载
FileAPI = {
// 只需要下面中的一个
jsPath: '/js/FileAPI.min.js/folder/', // 放本地上
jsUrl: 'yourcdn.com/js/FileAPI.min.js', // 放服务器上
// 只需要其中一个静态路径或flashUrl:
staticPath: '/flash/FileAPI.flash.swf/folder/',
flashUrl: 'yourcdn.com/js/FileAPI.flash.swf'
// forceLoad: true, html5: false
// noContentTimeout: 10000
}
</script>
<script src="angular-file-upload-shim.min.js"></script>
老浏览器已知的bug
- 由于flash的限制,如果服务器没有发送任何response body,响应状态码,则将永远是
204 ''No Content
,所以如果要访问服务器上传码,至少需要返回一个状态码才能正常工作 - 自定义headers,不支持
- 由于flash bug, Server HTTP 错误码400将以200返回给客户端。因此避免从服务端返回上传响应的结果状态码400,因为客户端会以200当作成功
- 错误响应(http code >= 400) 自定义错误信息,由于flash,将不支持
- 不允许 'PUT' 请求