AngularJS+Bootstrap實(shí)現(xiàn)多文件上傳與管理
最近一個(gè)項(xiàng)目中需要實(shí)現(xiàn)多文件上傳與管理,而項(xiàng)目是基于bootstrap開發(fā)的,所以查了一些bootstrap文件上傳插件,最后發(fā)現(xiàn)還是bootstrap-fileinput最美觀,該插件可以實(shí)現(xiàn)多文件的上傳與管理(插件官方地址:http://plugins.krajee.com/file-input),具體的效果如下:
(bootstrap-fileinput不局限于圖片上傳,也可以實(shí)現(xiàn)文件上傳,但圖片的縮略圖容易辨識(shí),這里就以圖片上傳為例)
該插件基本的操作可以參考:JS文件上傳神器bootstrap fileinput詳解,本文主要針對(duì)多文件管理。
在講該插件如何使用前,先跟大家講一下項(xiàng)目中關(guān)于圖片管理的需求:
1、可以上傳多個(gè)圖片
2、只有當(dāng)點(diǎn)擊保存按鈕時(shí),圖片信息才保存至數(shù)據(jù)庫(kù)
3、可以加載已經(jīng)保存到數(shù)據(jù)庫(kù)的圖片信息,并提供刪除功能
因此,我們可以規(guī)定幾個(gè)文件狀態(tài):
已選擇:已經(jīng)放入到插件中,但還沒有上傳到服務(wù)器。如上圖中第3個(gè)圖片,該圖片下方有上傳按鈕。
已上傳:已經(jīng)上傳到服務(wù)器,但圖片信息沒有保存到數(shù)據(jù)庫(kù)。如上圖中第2個(gè)圖片,該圖片下方有100%的進(jìn)度條。
已保存:圖片信息已經(jīng)保存至數(shù)據(jù)庫(kù)的圖片,如上圖中第1張圖,這些圖片下方有刪除按鈕,點(diǎn)擊刪除時(shí)會(huì)將圖片信息從數(shù)據(jù)庫(kù)中刪除。
一、引入必要文件
<link href="<%=path%>/static/css/bootstrap-3.3.5/bootstrap.min.css" rel="stylesheet"> <link href="<%=path%>/static/css/bootstrap-3.3.5/fileinput.css" rel="stylesheet"> <script src="<%=path%>/static/js/jquery-1.11.3.js"></script> <script src="<%=path%>/static/js/angularjs-1.3.9/angular.min.js"></script> <script src="<%=path%>/static/js/bootstrap-3.3.5/bootstrap.min.js"></script> <script src="<%=path%>/static/js/bootstrap-3.3.5/fileinput.js"></script> <script src="<%=path%>/static/js/bootstrap-3.3.5/fileinput_locale_zh.js"></script>
其中fileinput.js和fileinput_locale_zh.js都在插件待官方包中,angular.min.js和bootstrap.min.js就不多介紹了
二、多文件上傳
首先在頁(yè)面中定義file控件:
<input id="input-images" type="file" multiple class="file-loading" accept="image/*">
然后對(duì)該控件進(jìn)行初始化,就可以實(shí)現(xiàn)該組件的多文件上傳了:
$("#input-images").fileinput({ uploadUrl: "<%=path%>" + "/album/pictureFileUpload", allowedFileExtensions: ["jpg", "png", "gif"], resizePreference: 'height', maxFileCount: 10, language: 'zh', overwriteInitial: false, resizeImage: true, });
當(dāng)然,初始化時(shí)的屬性有很多,這里不一一介紹了,后臺(tái)代碼(使用JFinal)如下:
public void pictureFileUpload() { UploadFile uploadFile = getFile(); renderJson("{\"link\":" + "\"/fileinput/upload/" + uploadFile.getFileName() + "\"" + ",\"fileName\":\"" + uploadFile.getOriginalFileName() + "\"}"); }
注意最后一定要返回Json,哪怕返回一個(gè)空json串(“{}”),返回的值保存在前臺(tái)的data.response中。
三、已有文件的加載與刪除
已有文件的加載是指將服務(wù)器上已經(jīng)存在的文件展示在該控件中,以實(shí)現(xiàn)文件管理,提供刪除功能,這主要依賴于initialPreview實(shí)現(xiàn)的。
將服務(wù)器上的文件名稱和文件地址獲取之后,使用initialPreview和initialPreviewConfig完成加載和定義刪除操作:
var initPreview = new Array();//展示元素 var initPreviewConfig = new Array();//展示設(shè)置 $.post( "<%=path%>" + "/album/getPicsByAlbum", {albumId : albumId}, function(result) { for(var i=0;i<result.length;i++){ var pictureFile = result[i]; //用于展示已經(jīng)上傳的圖片 initPreview.push("<img src='" + pictureFile.PICADDRESS + "' class='file-preview-image' alt='"+pictureFile.PICNAME+"' title='"+pictureFile.PICNAME+"'>"); var config = new Object(); config.caption = pictureFile.PICNAME; config.url="<%=path%>" + "/album/deletePicById"; config.key=pictureFile.ID; initPreviewConfig.push(config); } initFileInput($scope); $("#input-images").fileinput('refresh', { initialPreview: initPreview, initialPreviewConfig: initPreviewConfig }); } );
點(diǎn)擊刪除圖標(biāo),會(huì)默認(rèn)把config中待key值傳至后臺(tái),后臺(tái)中定義deletePicById方法即可:
public void deletePicById() { String picId = getPara("key"); service.deletePicById(Integer.valueOf(picId)); renderJson("{}"); }
四、幾點(diǎn)疑問的解答
1、為什么model里沒有屬性,卻可以在前端展示相關(guān)屬性?
這里主要使用了JFinal的ActiveRecord功能,無(wú)需定義屬性和setter,getter方法,屬性值被映射在model里的attrs里,這個(gè)屬性是<key, value>的鍵值對(duì),而key值就是數(shù)據(jù)庫(kù)的字段名。 特別提醒:雖然SQL語(yǔ)句不分區(qū)大小寫,但字段名還是存在大小寫的,如果字段名是大寫的,那么映射到model里的key就是大寫的,同時(shí)JFinal的默認(rèn)id為主鍵的策略也不能生效,需要在 configPlugin中設(shè)置,如下:arp.addMapping("pictures", "ID", Picture.class),建議大家按照J(rèn)ava命名規(guī)范命名數(shù)據(jù)庫(kù)字段。
2、(參考代碼)中初始化FileInput為什么要執(zhí)行clear,destory操作?
因?yàn)镕ileInput插件在選擇文件后,不管有沒有上傳,都會(huì)保留文件在file域中,因此再點(diǎn)擊時(shí)會(huì)顯示上一次選擇的文件,不符合多相冊(cè)管理的需求,原本以為clear操作就可以清空f(shuō)ile域(官方文檔這么說(shuō)的),但實(shí)際操作發(fā)現(xiàn)并沒有清空,因此才調(diào)用clear,destory后再重新初始化文件上傳控件。(這一點(diǎn)不太確定,希望有大神可以指點(diǎn))
3、保存時(shí)怎么知道那些圖片需要存數(shù)據(jù)庫(kù),這是基于什么實(shí)現(xiàn)的?
$scope上有個(gè)selectedPics數(shù)組,該屬性負(fù)責(zé)保存最終那些文件會(huì)保存到數(shù)據(jù)庫(kù)。在文件選擇后會(huì)將選擇待文件信息保存到這個(gè)數(shù)組中,但hasUpload屬性為false;在文件上傳后,會(huì)修改對(duì)應(yīng)的hasUpload為true;在上傳成功后執(zhí)行刪除(還沒有保存到數(shù)據(jù)庫(kù))會(huì)從數(shù)組中移除對(duì)應(yīng)的元素。有人會(huì)問,那選擇文件后不上傳直接刪除,那文件信息豈不是會(huì)占用數(shù)據(jù)位置從而導(dǎo)致元素錯(cuò)亂嗎?其實(shí)并不會(huì),在fileuploaded事件中,哪些圖片已經(jīng)hasUpload,是直接改數(shù)組對(duì)應(yīng)位置元素的值的,而數(shù)組坐標(biāo)是通過(guò)圖片所在DIV的data-fileindex屬性值獲得的, 該值會(huì)一直增加,不會(huì)替補(bǔ)空缺值,不會(huì)因?yàn)閯h除圖片而變動(dòng),正好與selectedPics數(shù)組相對(duì)應(yīng)。
var idx = $("#"+previewId).attr("data-fileindex");
例如我選擇了3張圖片,此時(shí)沒有上傳,他們依次的data-fileindex為0,1,2,當(dāng)我刪除中間那個(gè)圖片并重新選擇新圖片時(shí),那么他們的data-fileindex就會(huì)變?yōu)?,2,3。
五、代碼參考
最后本人才學(xué)AngularJS,代碼寫的不夠純熟,如有不妥之處,歡迎大家留言,示例代碼在文章末尾,數(shù)據(jù)庫(kù)腳本為files.sql(MySQL),大家多看看代碼吧。
源碼下載:http://xiazai.jb51.net/201611/yuanma/BSfileinput(jb51.net).rar
如果大家還想深入學(xué)習(xí),可以點(diǎn)擊這里進(jìn)行學(xué)習(xí),再為大家附兩個(gè)精彩的專題:Bootstrap學(xué)習(xí)教程 Bootstrap實(shí)戰(zhàn)教程
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
- 基于angularjs實(shí)現(xiàn)圖片放大鏡效果
- angularjs實(shí)現(xiàn)多張圖片上傳并預(yù)覽功能
- AngularJs上傳前預(yù)覽圖片的實(shí)例代碼
- AngularJS 文件上傳控件 ng-file-upload詳解
- 通過(guò)AngularJS實(shí)現(xiàn)圖片上傳及縮略圖展示示例
- 學(xué)習(xí)使用AngularJS文件上傳控件
- AngularJS向后端ASP.NET API控制器上傳文件
- angularjs客戶端實(shí)現(xiàn)壓縮圖片文件并上傳實(shí)例
- angularjs點(diǎn)擊圖片放大實(shí)現(xiàn)上傳圖片預(yù)覽
相關(guān)文章
Javascript實(shí)現(xiàn)信息滾動(dòng)效果
這篇文章主要為大家詳細(xì)介紹了Javascript實(shí)現(xiàn)信息滾動(dòng)效果,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-05-05如何確保JavaScript的執(zhí)行順序 之實(shí)戰(zhàn)篇
我曾在文章《如何在多個(gè)頁(yè)面使用同一個(gè)HTML片段 - 續(xù)》的最后提到JavaScript順序執(zhí)行的特性。雖然現(xiàn)代瀏覽器可以并行的下載JavaScript(部分瀏覽器),但考慮到JavaScript的依賴關(guān)系,他們的執(zhí)行依然是按照引入順序進(jìn)行的。2011-03-03關(guān)于localStorage的存儲(chǔ),讀取,刪除
這篇文章主要介紹了關(guān)于localStorage的存儲(chǔ),讀取,刪除方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-04-04ES6 javascript中class類的get與set用法實(shí)例分析
這篇文章主要介紹了ES6 javascript中class類的get與set用法,結(jié)合具體實(shí)例形式分析了ES6中類的get與set關(guān)鍵字使用方法,需要的朋友可以參考下2017-10-10JS實(shí)現(xiàn)的簡(jiǎn)潔縱向滑動(dòng)菜單(滑動(dòng)門)效果
這篇文章主要介紹了JS實(shí)現(xiàn)的簡(jiǎn)潔縱向滑動(dòng)菜單(滑動(dòng)門)效果,通過(guò)簡(jiǎn)單的頁(yè)面元素遍歷實(shí)現(xiàn)華東切換的功能,具有一定參考借鑒價(jià)值,需要的朋友可以參考下2015-10-10