如何使用 Uploadset 实现挂起的附件?
How to Implement Pending Attachments with Uploadset?
没有发布好的、完整的指南来帮助用户加快了解如何使用更新的 UploadSet 控件实现挂起的附件。
***欢迎改进。
这是带有附加功能的待上传的完整实现,例如:
- 加载附件,
- CheckBox 到 (de)select 所有文件以方便用户,
- 下载,然后
- 忙碌指示灯,而 Uploading/Downloading。
提示:避免使用另一个名为 UploadCollection
的控件,它有太多错误,并且在寻找替代方案时浪费了太多时间。 UploadSet
是你的 bug-free 闪亮,最好的朋友。
外观:*复选框的对齐和控件视觉效果的修改是通过自定义完成的 CSS(在此答案中引用)
Pre-requisites:
- 脚手架
sap/m/MessageBox
为 MessageBox
和 sap/m/MessageToast
为 MessageToast
UploadSet
的命名空间:xmlns:up="sap.m.upload"
- 定义
var that
= this
全局或在每个函数中使用 that
查看:
<up:UploadSet id="attachmentUpl" instantUpload="false" maxFileSize="2" noDataDescription="" noDataText="" selectionChanged="onSelectionChangeAttachment"
uploadCompleted="onUploadCompleted" uploadUrl="/sap/opu/odata/sap/Z9NRS_CONFIG_SRV/Z9NRS_REQ_ATTACHSet" visible="true">
<up:toolbar>
<OverflowToolbar>
<CheckBox id="checkbox" select="onSelectAllAttachments" visible="false" />
<ToolbarSpacer/>
<Button id="upload" enabled="true" text="Upload" press="onStartUpload" type="Transparent" visible="true" />
<Button id="remove" enabled="false" icon="sap-icon://delete" press="onRemove" type="Transparent" visible="true" />
<Button id="download" enabled="false" icon="sap-icon://download" press="onDownload" type="Transparent" visible="true" />
</OverflowToolbar>
</up:toolbar>
</up:UploadSet>
控制器:
在onInit
内:
var oAttachmentUpl= this.byId('attachmentUpl').getDefaultFileUploader();
oAttachmentUpl.setIcon("sap-icon://add").setIconOnly(true);
oAttachmentUpl.setMultiple(true); //lets user select more than 1file at a time in their FileExplorer
加载附件:
loadAttachments:function(){
var sPath= "/Z9NRS_REQ_ATTACHSet?$filter=(ZNRS_REQUEST eq '"+sRequestId+"')";
var oAttachmentUpl= this.byId("attachmentUpl");
oAttachmentUpl.getList().setMode("MultiSelect");
this.getView().getModel().read(sPath,{
success:function(oData){
var oAttachmentsModel= new JSONModel(oData);
oAttachmentUpl.setModel(oAttachmentsModel).bindAggregation("items", "/results", new sap.m.upload.UploadSetItem({
fileName: "{FILE_NAME}", mediaType: "{MIME_TYPE}", visibleEdit:false, visibleRemove:false,
url: "/sap/opu/odata/sap/Z9NRS_CONFIG_SRV/Z9NRS_REQ_ATTACHSet(ZNRS_REQUEST='" + "{OBJECT_ID}" + "',FILE_NAME='" + "{FILE_NAME}" + "')/$value"
}));
if(oAttachmentUpl.getItems().length>0){
that.byId('checkbox').setVisible(true);
}
},
error:function(oError){that.parseErrorMsg()}
});
}
其他一切:
onSelectAllAttachments: function(oEvent) {
var aUploadedItems = this.byId("attachmentUpl").getItems(),
bSelected = oEvent.getSource().getSelected();
if (bSelected) { //if CheckBox is selected
aUploadedItems.forEach(oItem => oItem.getListItem().setSelected(true));
this.byId('download').setEnabled(true);
} else {
aUploadedItems.forEach(oItem => oItem.getListItem().setSelected(false));
this.byId('remove').setEnabled(false);
this.byId('download').setEnabled(false);
}
},
onSelectionChangeAttachment: function() {
if (this.byId("attachmentUpl").getList().getSelectedItems().length > 0) { //if user selects 1 or more uploaded item
this.byId("remove").setEnabled(true);
this.byId("download").setEnabled(true);
} else {
this.byId("remove").setEnabled(false);
this.byId("download").setEnabled(false);
}
},
onRemove: function(oEvent) {
var oAttachmentUpl = this.byId("attachmentUpl");
oAttachmentUpl.setBusy(true);
oAttachmentUpl.getItems().forEach(oItem => {
if (oItem.getListItem().getSelected()) {
var sPath = oItem.getProperty("url").split("SRV")[1]; //eg /Z9NRS_REQ_ATTACHSet
this.getView().getModel().remove(sPath, {
success: function() {
oAttachmentUpl.removeItem(oItem); //remove from displayed list
},
error: function(oError) {
that.parseErrorMsg();
}
});
}
});
oEvent.getSource().setEnabled(false);
this.byId("download").setEnabled(false);
if (oAttachmentUpl.getItems().length > 0) {
this.byId('checkbox').setVisible(true);
} else {
this.byId('checkbox').setVisible(false);
}
oAttachmentUpl.setBusy(false);
},
onDownload: function(oEvent) {
var oAttachmentUpl = this.byId("attachmentUpl");
oAttachmentUpl.setBusy(true);
oAttachmentUpl.getItems().forEach(oItem => {
if (oItem.getListItem().getSelected()) {
oItem.download(true);
oItem.getListItem().setSelected(false);
}
});
oAttachmentUpl.setBusy(false);
oEvent.getSource().setEnabled(false);
},
onStartUpload: function() {
var oAttachmentUpl = this.byId("attachmentUpl");
var aIncompleteItems = oAttachmentUpl.getIncompleteItems();
this.iIncompleteItems = aIncompleteItems.length; //used to turn off busy indicator upon completion of all pending uploads
if (this.iIncompleteItems !== 0) {
oAttachmentUpl.setBusy(true);
this.i = 0; //used to turn off busy indicator when all uploads complete
for (var i = 0; i < this.iIncompleteItems; i++) {
var sFileName = aIncompleteItems[i].getProperty("fileName");
var oXCSRFToken = new sap.ui.core.Item({
key: "X-CSRF-Token",
text: this.getOwnerComponent().getModel().getSecurityToken()
});
var oSlug = new sap.ui.core.Item({
key: "SLUG",
text: this.sRequestId + "/" + sFileName
});
oAttachmentUpl.addHeaderField(oXCSRFToken).addHeaderField(oSlug).uploadItem(aIncompleteItems[i]);
oAttachmentUpl.removeAllHeaderFields(); //at least slug header field must be reset after each upload
}
}
},
onUploadCompleted: function() {
this.i += 1;
if (this.i === this.iIncompleteItems) { //turn off busy indicator when all attachments have completed uploading
this.byId('attachmentUpl').setBusy(false);
}
},
parseErrorMsg: function(oError) { //parses oData error messages dependent on different return values
var oMessage, sType;
if (oError.response) { //for update
sType = typeof oError.response;
if (sType === "string" || sType === "object") oMessage = JSON.parse(oError.response.body).error.message.value;
else return MessageBox.error("Unhandled server error:\n\n" + oError.response + "\n\nReport this issue to Admin for a future fix.");
} else if (oError.responseText) { //for create
sType = typeof oError.responseText;
if (sType === "string" || sType === "object") oMessage = JSON.parse(oError.responseText).error.message.value;
else return MessageBox.error("Unhandled server error:\n\n" + oError.responseText + "\n\nReport this issue to Admin for a future fix.");
} else if (!oError) return MessageToast.show("Error message is undefined");
MessageBox.error(oMessage);
}
- CSS:
/*uploadSet: align toolbar checkbox with ListItems' checkboxes*/
.sapMIBar.sapMTB.sapMTBNewFlex.sapMTBInactive.sapMTBStandard.sapMTB-Transparent-CTX {
padding-left: 2px;
}
/*uploadSet: reduce height of each uploadItem*/
.sapMLIB.sapMLIB-CTX.sapMLIBShowSeparator.sapMLIBTypeInactive.sapMLIBFocusable.sapMCLI.sapMUCItem {
padding-top: 10px;
padding-bottom: 5px;
}
/*uploadSet: align uploadItem checkboxes to center*/
.sapMCb.sapMLIBSelectM {
align-self: center !important;
}
/*uploadSet: remove rename icon from pending files*/
.sapMBtnBase.sapMBtn.sapMUCEditBtn.sapMUCFirstButton {
display: none;
}
/*uploadSet: remove pending bar and text*/
.sapMFlexBox.sapMVBox.sapMFlexBoxJustifyStart.sapMFlexBoxAlignItemsStretch.sapMFlexBoxWrapNoWrap.sapMFlexBoxAlignContentStretch.sapMFlexBoxBGTransparent.sapMUSProgressBox {
display: none;
}
/*uploadSet: center the x button for pending files*/
.sapMUCButtonContainer {
align-self: center;
}
只需按下 Upload
按钮(位于 UploadSet 的工具栏中)即可上传所有待处理的附件。
所有项目都需要自定义才能使您的实施正常工作:
sPath
用于 loadAttachments
函数中的 oData 调用以及 UploadSetItem 中的几乎所有参数
uploadUrl
属性 你的 UploadSet
控制
sPath
用于 onRemove
函数中的 oData 调用
- SLUG header
text
onStartUpload
函数中的值
不包括的功能:
- 上传完成后刷新UploadSet的项目列表
附加功能:
- 不支持的文件类型,超过文件大小,Multi-File 进度(上传失败:
查看:将以下属性添加到您的 UploadSet,示例如下:
beforeUploadStarts="onBeforeUploadStarts" //this will update multi-file upload progress through MessageToast and MessageBox prompts
fileTypes="pdf,doc,docx,docm,ppt,pptx,xls,xlsx,jpg,jpeg,png"
fileTypeMismatch="onFileTypeMismatch"
maxFileSize="2"
fileSizeExceeded="onFileSizeExceeded"
控制器:
onBeforeUploadStarts: function(oEvent) { //track file upload progress
var oUploadSet = oEvent.getSource(),
iOldList = oUploadSet.getIncompleteItems().length;
setTimeout(() => this.checkFileUploadFailed(oUploadSet, iOldList), 10000); // recursive func that checks status of itemslist
},
checkFileUploadFailed: function(oUploadSet, iOldList) {
if (iOldList !== 0) {
var iNewList = oUploadSet.getIncompleteItems().length;
if (iNewList === iOldList) {
MessageToast.show("File upload(s) pending");
if (!this.iPendingFilesCounter) this.iPendingFilesCounter = 0;
this.iPendingFilesCounter += 1;
if (this.iPendingFilesCounter === 3) {
MessageBox.error("File uploads taking longer than expected.");
oUploadSet.setBusy(false);
}
var iOldList = iNewList;
setTimeout(() => this.checkFileUploadFailed(oUploadSet, iOldList), 10000);
}
}
},
onFileTypeMismatch: function(oEvent) {
var oItem = oEvent.getParameter("item");
this.byId("attachmentUpl").removeIncompleteItem(oItem); //remove pending item user tried to add
new sap.m.MessageToast.show(oItem.getProperty("fileName").split(".")[1] + " file type is not supported"); //show message toast with the specific fileType that isn't supported
}
onFileSizeExceeded: function(oEvent) {
var oAttachmentUpl = this.byId("attachmentUpl"),
oItem = oEvent.getParameter("item");
oAttachmentUpl.removeIncompleteItem(oItem); //remove pending item user tried to add
new sap.m.MessageToast.show("Maximum file size of " + oAttachmentUpl.getMaxFileSize() + " MB exceeded"); //show message toast with the max file size supported
}
没有发布好的、完整的指南来帮助用户加快了解如何使用更新的 UploadSet 控件实现挂起的附件。
***欢迎改进。
这是带有附加功能的待上传的完整实现,例如:
- 加载附件,
- CheckBox 到 (de)select 所有文件以方便用户,
- 下载,然后
- 忙碌指示灯,而 Uploading/Downloading。
提示:避免使用另一个名为 UploadCollection
的控件,它有太多错误,并且在寻找替代方案时浪费了太多时间。 UploadSet
是你的 bug-free 闪亮,最好的朋友。
外观:*复选框的对齐和控件视觉效果的修改是通过自定义完成的 CSS(在此答案中引用)
Pre-requisites:
- 脚手架
sap/m/MessageBox
为MessageBox
和sap/m/MessageToast
为MessageToast
UploadSet
的命名空间:xmlns:up="sap.m.upload"
- 定义
var that
=this
全局或在每个函数中使用that
查看:
<up:UploadSet id="attachmentUpl" instantUpload="false" maxFileSize="2" noDataDescription="" noDataText="" selectionChanged="onSelectionChangeAttachment" uploadCompleted="onUploadCompleted" uploadUrl="/sap/opu/odata/sap/Z9NRS_CONFIG_SRV/Z9NRS_REQ_ATTACHSet" visible="true"> <up:toolbar> <OverflowToolbar> <CheckBox id="checkbox" select="onSelectAllAttachments" visible="false" /> <ToolbarSpacer/> <Button id="upload" enabled="true" text="Upload" press="onStartUpload" type="Transparent" visible="true" /> <Button id="remove" enabled="false" icon="sap-icon://delete" press="onRemove" type="Transparent" visible="true" /> <Button id="download" enabled="false" icon="sap-icon://download" press="onDownload" type="Transparent" visible="true" /> </OverflowToolbar> </up:toolbar> </up:UploadSet>
控制器:
在onInit
内:
var oAttachmentUpl= this.byId('attachmentUpl').getDefaultFileUploader();
oAttachmentUpl.setIcon("sap-icon://add").setIconOnly(true);
oAttachmentUpl.setMultiple(true); //lets user select more than 1file at a time in their FileExplorer
加载附件:
loadAttachments:function(){
var sPath= "/Z9NRS_REQ_ATTACHSet?$filter=(ZNRS_REQUEST eq '"+sRequestId+"')";
var oAttachmentUpl= this.byId("attachmentUpl");
oAttachmentUpl.getList().setMode("MultiSelect");
this.getView().getModel().read(sPath,{
success:function(oData){
var oAttachmentsModel= new JSONModel(oData);
oAttachmentUpl.setModel(oAttachmentsModel).bindAggregation("items", "/results", new sap.m.upload.UploadSetItem({
fileName: "{FILE_NAME}", mediaType: "{MIME_TYPE}", visibleEdit:false, visibleRemove:false,
url: "/sap/opu/odata/sap/Z9NRS_CONFIG_SRV/Z9NRS_REQ_ATTACHSet(ZNRS_REQUEST='" + "{OBJECT_ID}" + "',FILE_NAME='" + "{FILE_NAME}" + "')/$value"
}));
if(oAttachmentUpl.getItems().length>0){
that.byId('checkbox').setVisible(true);
}
},
error:function(oError){that.parseErrorMsg()}
});
}
其他一切:
onSelectAllAttachments: function(oEvent) {
var aUploadedItems = this.byId("attachmentUpl").getItems(),
bSelected = oEvent.getSource().getSelected();
if (bSelected) { //if CheckBox is selected
aUploadedItems.forEach(oItem => oItem.getListItem().setSelected(true));
this.byId('download').setEnabled(true);
} else {
aUploadedItems.forEach(oItem => oItem.getListItem().setSelected(false));
this.byId('remove').setEnabled(false);
this.byId('download').setEnabled(false);
}
},
onSelectionChangeAttachment: function() {
if (this.byId("attachmentUpl").getList().getSelectedItems().length > 0) { //if user selects 1 or more uploaded item
this.byId("remove").setEnabled(true);
this.byId("download").setEnabled(true);
} else {
this.byId("remove").setEnabled(false);
this.byId("download").setEnabled(false);
}
},
onRemove: function(oEvent) {
var oAttachmentUpl = this.byId("attachmentUpl");
oAttachmentUpl.setBusy(true);
oAttachmentUpl.getItems().forEach(oItem => {
if (oItem.getListItem().getSelected()) {
var sPath = oItem.getProperty("url").split("SRV")[1]; //eg /Z9NRS_REQ_ATTACHSet
this.getView().getModel().remove(sPath, {
success: function() {
oAttachmentUpl.removeItem(oItem); //remove from displayed list
},
error: function(oError) {
that.parseErrorMsg();
}
});
}
});
oEvent.getSource().setEnabled(false);
this.byId("download").setEnabled(false);
if (oAttachmentUpl.getItems().length > 0) {
this.byId('checkbox').setVisible(true);
} else {
this.byId('checkbox').setVisible(false);
}
oAttachmentUpl.setBusy(false);
},
onDownload: function(oEvent) {
var oAttachmentUpl = this.byId("attachmentUpl");
oAttachmentUpl.setBusy(true);
oAttachmentUpl.getItems().forEach(oItem => {
if (oItem.getListItem().getSelected()) {
oItem.download(true);
oItem.getListItem().setSelected(false);
}
});
oAttachmentUpl.setBusy(false);
oEvent.getSource().setEnabled(false);
},
onStartUpload: function() {
var oAttachmentUpl = this.byId("attachmentUpl");
var aIncompleteItems = oAttachmentUpl.getIncompleteItems();
this.iIncompleteItems = aIncompleteItems.length; //used to turn off busy indicator upon completion of all pending uploads
if (this.iIncompleteItems !== 0) {
oAttachmentUpl.setBusy(true);
this.i = 0; //used to turn off busy indicator when all uploads complete
for (var i = 0; i < this.iIncompleteItems; i++) {
var sFileName = aIncompleteItems[i].getProperty("fileName");
var oXCSRFToken = new sap.ui.core.Item({
key: "X-CSRF-Token",
text: this.getOwnerComponent().getModel().getSecurityToken()
});
var oSlug = new sap.ui.core.Item({
key: "SLUG",
text: this.sRequestId + "/" + sFileName
});
oAttachmentUpl.addHeaderField(oXCSRFToken).addHeaderField(oSlug).uploadItem(aIncompleteItems[i]);
oAttachmentUpl.removeAllHeaderFields(); //at least slug header field must be reset after each upload
}
}
},
onUploadCompleted: function() {
this.i += 1;
if (this.i === this.iIncompleteItems) { //turn off busy indicator when all attachments have completed uploading
this.byId('attachmentUpl').setBusy(false);
}
},
parseErrorMsg: function(oError) { //parses oData error messages dependent on different return values
var oMessage, sType;
if (oError.response) { //for update
sType = typeof oError.response;
if (sType === "string" || sType === "object") oMessage = JSON.parse(oError.response.body).error.message.value;
else return MessageBox.error("Unhandled server error:\n\n" + oError.response + "\n\nReport this issue to Admin for a future fix.");
} else if (oError.responseText) { //for create
sType = typeof oError.responseText;
if (sType === "string" || sType === "object") oMessage = JSON.parse(oError.responseText).error.message.value;
else return MessageBox.error("Unhandled server error:\n\n" + oError.responseText + "\n\nReport this issue to Admin for a future fix.");
} else if (!oError) return MessageToast.show("Error message is undefined");
MessageBox.error(oMessage);
}
- CSS:
/*uploadSet: align toolbar checkbox with ListItems' checkboxes*/
.sapMIBar.sapMTB.sapMTBNewFlex.sapMTBInactive.sapMTBStandard.sapMTB-Transparent-CTX {
padding-left: 2px;
}
/*uploadSet: reduce height of each uploadItem*/
.sapMLIB.sapMLIB-CTX.sapMLIBShowSeparator.sapMLIBTypeInactive.sapMLIBFocusable.sapMCLI.sapMUCItem {
padding-top: 10px;
padding-bottom: 5px;
}
/*uploadSet: align uploadItem checkboxes to center*/
.sapMCb.sapMLIBSelectM {
align-self: center !important;
}
/*uploadSet: remove rename icon from pending files*/
.sapMBtnBase.sapMBtn.sapMUCEditBtn.sapMUCFirstButton {
display: none;
}
/*uploadSet: remove pending bar and text*/
.sapMFlexBox.sapMVBox.sapMFlexBoxJustifyStart.sapMFlexBoxAlignItemsStretch.sapMFlexBoxWrapNoWrap.sapMFlexBoxAlignContentStretch.sapMFlexBoxBGTransparent.sapMUSProgressBox {
display: none;
}
/*uploadSet: center the x button for pending files*/
.sapMUCButtonContainer {
align-self: center;
}
只需按下 Upload
按钮(位于 UploadSet 的工具栏中)即可上传所有待处理的附件。
所有项目都需要自定义才能使您的实施正常工作:
sPath
用于loadAttachments
函数中的 oData 调用以及 UploadSetItem 中的几乎所有参数
uploadUrl
属性 你的UploadSet
控制sPath
用于onRemove
函数中的 oData 调用- SLUG header
text
onStartUpload
函数中的值
不包括的功能:
- 上传完成后刷新UploadSet的项目列表
附加功能:
- 不支持的文件类型,超过文件大小,Multi-File 进度(上传失败:
查看:将以下属性添加到您的 UploadSet,示例如下:
beforeUploadStarts="onBeforeUploadStarts" //this will update multi-file upload progress through MessageToast and MessageBox prompts
fileTypes="pdf,doc,docx,docm,ppt,pptx,xls,xlsx,jpg,jpeg,png"
fileTypeMismatch="onFileTypeMismatch"
maxFileSize="2"
fileSizeExceeded="onFileSizeExceeded"
控制器:
onBeforeUploadStarts: function(oEvent) { //track file upload progress
var oUploadSet = oEvent.getSource(),
iOldList = oUploadSet.getIncompleteItems().length;
setTimeout(() => this.checkFileUploadFailed(oUploadSet, iOldList), 10000); // recursive func that checks status of itemslist
},
checkFileUploadFailed: function(oUploadSet, iOldList) {
if (iOldList !== 0) {
var iNewList = oUploadSet.getIncompleteItems().length;
if (iNewList === iOldList) {
MessageToast.show("File upload(s) pending");
if (!this.iPendingFilesCounter) this.iPendingFilesCounter = 0;
this.iPendingFilesCounter += 1;
if (this.iPendingFilesCounter === 3) {
MessageBox.error("File uploads taking longer than expected.");
oUploadSet.setBusy(false);
}
var iOldList = iNewList;
setTimeout(() => this.checkFileUploadFailed(oUploadSet, iOldList), 10000);
}
}
},
onFileTypeMismatch: function(oEvent) {
var oItem = oEvent.getParameter("item");
this.byId("attachmentUpl").removeIncompleteItem(oItem); //remove pending item user tried to add
new sap.m.MessageToast.show(oItem.getProperty("fileName").split(".")[1] + " file type is not supported"); //show message toast with the specific fileType that isn't supported
}
onFileSizeExceeded: function(oEvent) {
var oAttachmentUpl = this.byId("attachmentUpl"),
oItem = oEvent.getParameter("item");
oAttachmentUpl.removeIncompleteItem(oItem); //remove pending item user tried to add
new sap.m.MessageToast.show("Maximum file size of " + oAttachmentUpl.getMaxFileSize() + " MB exceeded"); //show message toast with the max file size supported
}