最近一個項目中需要實現多檔案上傳與管理,而項目是基於bootstrap開發的,所以查了一些bootstrap檔案上傳外掛程式,最後發現還是bootstrap-fileinput最美觀,該外掛程式可以實現多檔案的上傳與管理(外掛程式官方地址:http://plugins.krajee.com/file-input),具體的效果如下:
(bootstrap-fileinput不局限於圖片上傳,也可以實現檔案上傳,但圖片的縮圖容易辨識,這裡就以圖片上傳為例)
該外掛程式基本的操作可以參考:JS檔案上傳神器bootstrap fileinput詳解,本文主要針對多檔案管理。
在講該外掛程式如何使用前,先跟大家講一下項目中關於圖片管理的需求:
1、可以上傳多個圖片
2、只有當點擊儲存按鈕時,圖片資訊才儲存至資料庫
3、可以載入已經儲存到資料庫的圖片資訊,並提供刪除功能
因此,我們可以規定幾個檔案狀態:
已選擇:已經放入到外掛程式中,但還沒有上傳到伺服器。如上圖中第3個圖片,該圖片下方有上傳按鈕。
已上傳:已經上傳到伺服器,但圖片資訊沒有儲存到資料庫。如上圖中第2個圖片,該圖片下方有100%的進度條。
已儲存:圖片資訊已經儲存至資料庫的圖片,如上圖中第1張圖,這些圖片下方有刪除按鈕,點擊刪除時會將圖片資訊從資料庫中刪除。
一、引入必要檔案
<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就不多介紹了
二、多檔案上傳
首先在頁面中定義file控制項:
<input id="input-images" type="file" multiple class="file-loading" accept="image/*">
然後對該控制項進行初始化,就可以實現該組件的多檔案上傳了:
$("#input-images").fileinput({ uploadUrl: "<%=path%>" + "/album/pictureFileUpload", allowedFileExtensions: ["jpg", "png", "gif"], resizePreference: 'height', maxFileCount: 10, language: 'zh', overwriteInitial: false, resizeImage: true, });
當然,初始化時的屬性有很多,這裡不一一介紹了,後台代碼(使用JFinal)如下:
public void pictureFileUpload() { UploadFile uploadFile = getFile(); renderJson("{\"link\":" + "\"/fileinput/upload/" + uploadFile.getFileName() + "\"" + ",\"fileName\":\"" + uploadFile.getOriginalFileName() + "\"}"); }
注意最後一定要返回Json,哪怕返回一個空json串(“{}”),返回的值儲存在前台的data.response中。
三、已有檔案的載入與刪除
已有檔案的載入是指將伺服器上已經存在的檔案展示在該控制項中,以實現檔案管理,提供刪除功能,這主要依賴於initialPreview實現的。
將伺服器上的檔案名稱和檔案地址擷取之後,使用initialPreview和initialPreviewConfig完成載入和定義刪除操作:
var initPreview = new Array();//展示元素 var initPreviewConfig = new Array();//展示設定 $.post( "<%=path%>" + "/album/getPicsByAlbum", {albumId : albumId}, function(result) { for(var i=0;i<result.length;i++){ var pictureFile = result[i]; //用於展示已經上傳的圖片 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 }); } );
點擊刪除表徵圖,會預設把config中待key值傳至後台,後台中定義deletePicById方法即可:
public void deletePicById() { String picId = getPara("key"); service.deletePicById(Integer.valueOf(picId)); renderJson("{}"); }
四、幾點疑問的解答
1、為什麼model裡沒有屬性,卻可以在前端展示相關屬性?
這裡主要使用了JFinal的ActiveRecord功能,無需定義屬性和setter,getter方法,屬性值被映射在model裡的attrs裡,這個屬性是<key, value>的索引值對,而key值就是資料庫的欄位名。 特別提醒:雖然SQL語句不分區大小寫,但欄位名還是存在大小寫,如果欄位名是大寫的,那麼映射到model裡的key就是大寫的,同時JFinal的預設id為主鍵的策略也不能生效,需要在 configPlugin中設定,如下:arp.addMapping("pictures", "ID", Picture.class),建議大家按照Java命名規範命名資料庫欄位。
2、(參考代碼)中初始化FileInput為什麼要執行clear,destory操作?
因為FileInput外掛程式在選擇檔案後,不管有沒有上傳,都會保留檔案在file域中,因此再點擊時會顯示上一次選擇的檔案,不符合多相簿管理的需求,原本以為clear操作就可以清空file域(官方文檔這麼說的),但實際操作發現並沒有清空,因此才調用clear,destory後再重新初始設定檔案上傳控制項。(這一點不太確定,希望有大神可以指點)
3、儲存時怎麼知道那些圖片需要存資料庫,這是基於什麼實現的?
$scope上有個selectedPics數組,該屬性負責儲存最終那些檔案會儲存到資料庫。在檔案選擇後會將選擇待檔案資訊儲存到這個數組中,但hasUpload屬性為false;在檔案上傳後,會修改對應的hasUpload為true;在上傳成功後執行刪除(還沒有儲存到資料庫)會從數組中移除對應的元素。有人會問,那選擇檔案後不上傳直接刪除,那檔案資訊豈不是會佔用資料位元置從而導致元素錯亂嗎?其實並不會,在fileuploaded事件中,哪些圖片已經hasUpload,是直接改數組對應位置元素的值的,而數組座標是通過圖片所在DIV的data-fileindex屬性值獲得的, 該值會一直增加,不會替補空缺值,不會因為刪除圖片而變動,正好與selectedPics數組相對應。
var idx = $("#"+previewId).attr("data-fileindex");
例如我選擇了3張圖片,此時沒有上傳,他們依次的data-fileindex為0,1,2,當我刪除中間那個圖片並重新選擇新圖片時,那麼他們的data-fileindex就會變為0,2,3。
五、代碼參考
最後本人才學AngularJS,代碼寫的不夠純熟,如有不妥之處,歡迎大家留言,範例程式碼在文章末尾,資料庫指令碼為files.sql(MySQL),大家多看看代碼吧。
源碼下載:http://xiazai.jb51.net/201611/yuanma/BSfileinput(jb51.net).rar
如果大家還想深入學習,可以點擊這裡進行學習,再為大家附兩個精彩的專題:Bootstrap學習教程Bootstrap實戰教程
以上就是本文的全部內容,希望對大家的學習有所協助,也希望大家多多支援雲棲社區。