本文介绍如何在AngularJS项目中利用angular-file-upload插件实现文件上传功能。重点讲解如何通过CSS隐藏原生input并自定义按钮样式,解决原生样式不美观的问题。同时演示如何创建多个uploader对象以支持同时上传两个文件,并详细说明文件类型限制、多选配置及队列管理方法,帮助开发者快速掌握该插件的核心用法。
自定义文件上传按钮样式
在之前的项目开发中,遇到了一个文件上传的需求,期望实现的界面效果如图所示。

该需求要求能够同时上传两个文件,并对文件的格式和大小进行限制。由于前端采用了Angular框架,为了避免为了单一上传功能而引入jQuery,我在网络上搜索基于Angular的文件上传控件。鉴于Angular相对较新,当时似乎缺乏非常成熟的插件,网上的教程也多为复制粘贴,参考价值有限。幸运的是,最终找到了一个功能强大的插件,其使用方法清晰且强大,特此分享以助他人。
关于上传按钮的样式设计。我们知道文件上传通常使用<input type="file"/>标签,但该标签的默认样式往往不够美观,如下图所示。

在一个注重设计感的网站中,这种默认样式会显得格格不入。此外,如果需要在按钮前添加一个输入框来显示已选文件名,默认的显示区域该如何隐藏?接下来将介绍解决方法。
解决方法是使用一个<a>标签包裹<input>标签,并将<input>的opacity属性设置为0,从而实现隐藏原生控件并自定义外观的效果。具体代码实现如下。
HTML结构部分。
<div>
<input class="filename" type="text" readonly="readonly" />
<a href="javascript:;" name="file">
<input type="file" name="key"/>浏览
</a>
</div>
<div>
<input class="filename" type="text" readonly="readonly" />
<a href="javascript:;" name="file">
<input type="file" name="key"/>浏览
</a>
</div>
CSS样式部分。
.filename{
width: 300px;
height: 30px;
line-height: 30px;
}
a{
width: 50px;
text-align: center;
height: 30px;
line-height: 30px;
position: raletive;
cursor: pointer;
overflow:hidden;
display: inline-block;
}
a input{
position: absolute:
left: 0;
top: 0;
opacity: 0;
}
至此,样式调整完成,最终效果如下图所示。

通过控制前方的输入框,可以显示用户选择的文件名,整体视觉效果更加协调美观。

angular-file-upload插件使用指南
关于angular-file-upload插件的使用。
在提供的示例中可以找到所需文件。示例中引入的es5-shim.min.js文件是为了兼容旧版浏览器,这体现了该插件的强大兼容性。
接下来,我们将逐步使用该插件实现文件上传功能。
该插件定义了三个主要指令:nv-file-drop、nv-file-select和uploader。
从名称可以看出,第一个指令支持拖拽文件选择,第二个指令用于点击选择文件,而uploader指令则用于在控制器中绑定新建的upload对象。
HTML文件的具体实现。
<form class="form-horizontal" name="form">
<div class="form-line">
<label>请选择证书文件:</label><span class="small-tip">证书文件只支持.pem格式,文件大小1M以内</span>
<div class="choose-file-area">
<input class="file-name" type="text" readonly="readonly" ng-model="fileItem.name"/>
<a href="javascript:;" class="choose-book">
<input type="file" name="certificate" nv-file-select uploader="uploader" ng-click="clearItems()"/>浏览
</a>
</div>
</div>
<div class="form-line">
<label>请选择私钥文件:</label><span class="small-tip">私钥文件只支持.key格式,文件大小1M以内</span>
<div class="choose-file-area">
<input class="file-name" type="text" readonly="readonly" ng-model="fileItem1.name"/>
<a href="javascript:;" class="choose-key">
<input type="file" name="key" nv-file-select uploader="uploader1" ng-click="clearItems1()"/>浏览
</a>
</div>
</div>
<button type="submit" ng-click="UploadFile()">提交</button>
</form>
注意,由于需要上传两个文件,因此创建了两个upload对象,以便于分别管理文件和处理回调函数。最后,给上传按钮绑定点击事件,同时触发两个对象的上传操作。
控制器文件的具体实现。
var app = angular.module('app', ['angularFileUpload']);
app.controller('uploadController',['$scope', 'FileUploader', function($scope, FileUploader) {
$scope.uploadStatus = $scope.uploadStatus1 = false; //定义两个上传后返回的状态,成功获失败
var uploader = $scope.uploader = new FileUploader({
url: 'upload.php',
queueLimit: 1, //文件个数
removeAfterUpload: true //上传后删除文件
});
var uploader1 = $scope.uploader1 = new FileUploader({
url: 'upload.php',
queueLimit: 1,
removeAfterUpload: true
});
$scope.clearItems = function(){ //重新选择文件时,清空队列,达到覆盖文件的效果
uploader.clearQueue();
}
$scope.clearItems1 = function(){
uploader1.clearQueue();
}
uploader.onAfterAddingFile = function(fileItem) {
$scope.fileItem = fileItem._file; //添加文件之后,把文件信息赋给scope
};
uploader1.onAfterAddingFile = function(fileItem) {
$scope.fileItem1 = fileItem._file; //添加文件之后,把文件信息赋给scope
//能够在这里判断添加的文件名后缀和文件大小是否满足需求。
};
uploader.onSuccessItem = function(fileItem, response, status, headers) {
$scope.uploadStatus = true; //上传成功则把状态改为true
};
uploader1.onSuccessItem = function(fileItem,response, status, headers){
$scope.uploadStatus1 = true;
}
$scope.UploadFile = function(){
uploader.uploadAll();
uploader1.uploadAll();
if(status){
if(status1){
alert('上传成功!');
}else{
alert('证书成功!私钥失败!');
}
}else{
if(status1){
alert('私钥成功!证书失败!');
}else{
alert('上传失败!');
}
}
}
}])
总结部分。在上述示例中,定义两个upload对象是因为需要上传两个文件。每次重新选择文件时,应该覆盖之前选好的文件。如果只定义一个对象,操作覆盖位置会较为复杂;而定义两个对象,在重新选择时,可以先清空当前对象的文件队列,再添加新文件,操作更为简便。
后来发现,其实也可以不定义两个upload对象。因为该插件提供了removeFromQueue(index)方法,其中index是文件队列数组中文件的索引值。由于是两次选择文件,可以将队列长度控制在2,每次选择时调用该方法,根据位置传入0或1即可。
如果需要实现同一窗口内多选文件,只需在<input type="file" />标签上添加multiple="true"属性即可。
如果需要限制文件类型,可以使用<input type="file" accept="image/*" />属性进行限制。
accept属性的取值类型列表如下。
* accept="application/msexcel"
* accept="application/msword"
* accept="application/pdf"
* accept="application/poscript"
* accept="application/rtf"
* accept="application/x-zip-compressed"
* accept="audio/basic"
* accept="audio/x-aiff"
* accept="audio/x-mpeg"
* accept="audio/x-pn/realaudio"
* accept="audio/x-waw"
* accept="image/*"
* accept="image/gif"
* accept="image/jpeg"
* accept="image/tiff"
* accept="image/x-ms-bmp"
* accept="image/x-photo-cd"
* accept="image/x-png"
* accept="image/x-portablebitmap"
* accept="image/x-portable-greymap"
* accept="image/x-portable-pixmap"
* accept="image/x-rgb"
* accept="text/html"
* accept="text/plain"
* accept="video/quicktime"
* accept="video/x-mpeg2"
* accept="video/x-msvideo"
该插件还提供了丰富的配置参数、对象方法和回调函数,以满足不同的业务需求。
更多精彩内容请参考专题《ajax上传技术汇总》,《javascript文件上传操作汇总》和《jQuery上传操作汇总》进行学习。
以上就是关于AngularJS文件上传控件的使用方法介绍,希望对大家的学习有所帮助。