最近在做一个小项目,有个需求是批量上传图片。
ExtJs没有提供现成的批量上传控件,于是自己就在网上搜了一下,发现有人结合swfupload扩展了一下。
于是自己也打造了一个符合需求的控件。
先看一下效果图,现在比较简陋
编写过程中遇到的问题
1、刚开始在处理上传后自动将上传的图片添加到窗体里时,遇到如下情况
第一反应是没有收到返回的数据,然后console.log()打出接收的数据,发现数据也正常,如下图
我还在怀疑是不是dataview不能使用.getStore().add(model)这种方式添加。最后发现接收的是字符串,而不是object。应该使用Ext.JSON.decode()将字符串转成json对象:如图
这里大意了,至此第一个问题解决。
2、在当前窗口已存在图片的情况下再向其中插入图片会存在如下图的情况
即不满一行的情况下,若本次上传超过一行的数据,则会出现原来最后一个item与本次上传的项整体换行,通过开发者工具可以看到
第一条数据在一个class为x-dataview-item的div里,后来上传的图片都被添加到上一次最后一个div里了,奇怪的是我的tpl模版里根本没有这个div,
然后我又在api文档中查看了一下html代码,同样没有这个div。这个不可能凭空出来的啊,只能去找找ext的源码了。搜索dataview-item可以找到
itemCls: Ext.baseCSSPrefix + 'dataview-item',再往下走点就能找到itemTpl = Ext.String.format('<tpl for="."><div class="{0}">{1}</div></tpl>', me.itemCls, itemTpl);就是这里加上的。于是果断把这里改成itemTpl = Ext.String.format('<tpl for=".">{0}</tpl>', itemTpl);至此第二个问题也解决了。
不过还有些疑问,为什么api文档中就没有这种情况。
以下是整个代码
1 Ext.define('frame.PicturesUpload', { 2 extend: 'Ext.window.Window', 3 4 height: 447, 5 width: 531, 6 layout: { 7 type: 'border' 8 }, 9 title: '', 10 11 initComponent: function () { 12 var me = this; 13 14 var dataView = Ext.create('Ext.view.View', { 15 store: me.dvStore, 16 overflowY: 'auto', 17 itemTpl: [ 18 '<tpl for=".">', 19 '<div class="thumb-wrap" id="{name}">', 20 '<div class="thumb"><img src="{url}" title="{name}"></div>', 21 '<span class="x-editable">{shortName}</span></div>', 22 '</tpl>' 23 ], 24 multiSelect: true, 25 height: 310, 26 trackOver: true, 27 overItemCls: 'x-item-over', 28 itemSelector: 'div.thumb-wrap', 29 emptyText: '这里还没有图片', 30 prepareData: function (data) { 31 Ext.apply(data, { 32 shortName: Ext.util.Format.ellipsis(data.name, 15) 33 }); 34 return data; 35 }, 36 listeners: { 37 selectionchange: function (dv, nodes) { 38 var l = nodes.length, 39 s = l !== 1 ? 's' : ''; 40 me.setTitle('Simple DataView (' + l + ' item' + s + ' selected)'); 41 } 42 } 43 }); 44 this.DataView = dataView; 45 me.items = [{ 46 xtype: 'panel', 47 region: 'center', 48 layout: 'fit', 49 border: false, 50 items: dataView 51 }]; 52 53 var progressbar = Ext.create('Ext.ProgressBar', { 54 flex: 4, 55 value: 0 56 }); 57 this.Progressbar = progressbar; 58 59 var statusLabel = Ext.create('Ext.form.Label', { 60 flex: 1, 61 text: '已选择0个文件' 62 }); 63 this.StatusLabel = statusLabel; 64 me.dockedItems = [{ 65 xtype: 'toolbar', 66 dock: 'top', 67 items: [{ 68 id: 'swfuploadbutton', 69 width: 85, 70 xtype: 'panel', 71 border: false, 72 bodyStyle: 'background-color:transparent;' 73 }, { 74 text: '删除', 75 tooltip: '删除选中图片' 76 }] 77 }, 78 { 79 xtype: 'toolbar', 80 dock: 'bottom', 81 items: [ 82 statusLabel, 83 progressbar 84 ] 85 } 86 ]; 87 88 me.callParent(arguments); 89 }, 90 listeners: { 91 afterrender: function (t) { 92 t.SWFUpload = new SWFUpload({ 93 // Backend Settings 94 upload_url: "/Default/UploadPics", 95 post_params: { 96 hid: t.hid 97 }, 98 99 // File Upload Settings 100 file_types: "*.jpg;*.bmp;*.png;*.gif", 101 file_upload_limit: "0", // Zero means unlimited 102 103 // Event Handler Settings - these functions as defined in Handlers.js 104 // The handlers are not part of SWFUpload but are part of my website and control how 105 // my website reacts to the SWFUpload events. 106 file_queue_error_handler: fileQueueError, 107 file_dialog_complete_handler: function (numFilesSelected, numFilesQueued) { 108 try { 109 if (numFilesQueued > 0) { 110 t.StatusLabel.setText("已选择" + numFilesSelected + "个文件"); 111 this.startUpload(); 112 } 113 } catch (ex) { 114 this.debug(ex); 115 } 116 }, 117 upload_progress_handler: function (file, bytesLoaded) { 118 119 try { 120 121 var percent = Math.ceil((bytesLoaded / file.size) * 100); 122 t.Progressbar.setPosition(percent); 123 if (percent === 100) { 124 t.StatusLabel.setText("已完成"); 125 } else { 126 t.StatusLabel.setText("正在上传"); 127 } 128 } catch (ex) { 129 this.debug(ex); 130 } 131 }, 132 upload_error_handler: uploadError, 133 upload_success_handler: function (file, serverData) { 134 try { 135 var data = Ext.JSON.decode(serverData); 136 console.log(data); 137 t.DataView.getStore().add(data); 138 t.ProgressBar.setPosition(0); 139 } catch (ex) { 140 this.debug(ex); 141 } 142 }, 143 upload_complete_handler: function (file) { 144 try { 145 146 /* I want the next upload to continue automatically so I'll call startUpload here */ 147 if (this.getStats().files_queued > 0) { 148 this.startUpload(); 149 } else { 150 //t.DataView.getStore().load(); 151 t.StatusLabel.setText("已全部完成"); 152 } 153 } catch (ex) { 154 this.debug(ex); 155 } 156 }, 157 158 // Button settings 159 button_image_url: VirtualPath + "/content/images/uploadbutton.png", 160 button_placeholder_id: "swfuploadbutton", 161 button_width: 80, 162 button_height: 22, 163 button_text: '<span class="swfbutton">上传图片</span>', 164 button_text_style: '.swfbutton { font-family: Helvetica, Arial, sans-serif; font-size: 12pt;text-align:center; }', 165 // Flash Settings 166 flash_url: VirtualPath + "/content/js/swfupload/swfupload.swf", // Relative to this file 167 168 // Debug Settings 169 debug: false 170 }); 171 } 172 } 173 174 });
留此文以备以后查看。