給出一個完整例子躁绸,介紹如何對含有 Image 字段的數(shù)據(jù)進行增刪改查。本次文章借鑒和參考了網(wǎng)上一篇不錯的文章的素材和代碼,具體參見 【參考】 部分净刮。
UI 界面
主界面:
三個按鈕分別對應(yīng)新建剥哑、修改和刪除功能。用戶點擊 [Creare user]淹父,彈出如下對話框:
填寫資料株婴,點擊 [提交] 按鈕,可以新建用戶數(shù)據(jù)暑认。出于演示目的困介,新建用戶的時候,沒有處理圖片的代碼蘸际。
在存在行被選中的時候座哩,當用戶點擊 [Update user's data] 按鈕,彈出如下對話框粮彤,可以對用戶的數(shù)據(jù)進行修改根穷。Email 作為 關(guān)鍵字段不能修改 (僅處于技術(shù)演示目的),Photo 被統(tǒng)一替換成 OpenUI5 的 logo导坟。
在存在行被選中的時候屿良,當用戶點擊 [Delete user] 按鈕,彈出對話框確認是否刪除:
要點
本實例代碼主要說明下面的技術(shù)要點:
- 如何處理
Edm.Binary
字段 - 使用 SimpleForm 進行 CRUD 處理
- OpenUI5 mock server 的使用
代碼及說明
代碼文件主要在放在三個文件中:
metadata.xml
OpenUI5 的 mock server 需要說明 json 格式的元數(shù)據(jù) ( metadata):
<?xml version="1.0" encoding="utf-8" ?>
<edmx:Edmx Version="1.0"
xmlns:edmx="http://schemas.microsoft.com/ado/2007/06/edmx"
xmlns:m="http://schemas.microsoft.com/ado/2007/08/dataservices/metadata"
xmlns:sap="http://www.sap.com/Protocols/SAPData">
<edmx:DataServices m:DataServiceVersion="2.0">
<Schema Namespace="ZSA_USERS_SRV" xml:lang="en"
sap:schema-version="0000" xmlns="http://schemas.microsoft.com/ado/2008/09/edm">
<EntityType Name="User" sap:content-version="1">
<Key>
<PropertyRef Name="Email" />
</Key>
<Property Name="Email" Type="Edm.String" Nullable="false" />
<Property Name="Firstname" Type="Edm.String" Nullable="false" />
<Property Name="Lastname" Type="Edm.String" Nullable="false" />
<Property Name="Age" Type="Edm.Int32" Nullable="false" />
<Property Name="Address" Type="Edm.String" Nullable="false" />
<Property Name="Picture" Type="Edm.Binary" Nullable="true" />
</EntityType>
<EntityContainer Name="ZSA_USERS_SRV_Entities"
m:IsDefaultEntityContainer="true">
<EntitySet Name="Users" EntityType="ZSA_USERS_SRV.User"
sap:pageable="false" sap:content-version="1" />
</EntityContainer>
</Schema>
</edmx:DataServices>
</edmx:Edmx>
元數(shù)據(jù)要點:
- Email 字段為
Key
- Picture 字段的類型為
Edm.Binary
- Entity set 的名稱為
Users
, OpenUI5 根據(jù)名稱 Users 在當前文件夾下查找Users.json
文件惫周,并根據(jù) metadata 的格式來確定數(shù)據(jù)結(jié)構(gòu)尘惧。 - 一般情況下, 編程語言提供 metadata 的自動生成递递,并不需要手工編寫喷橙。
Users.json
一共包含三條數(shù)據(jù),第一個用戶有圖片漾狼,其他用戶沒有重慢。json 數(shù)據(jù)的 Base64 編碼略去,請參考源代碼:
[
{
"Email" : "john@doe.com",
"Firstname" : "John",
"Lastname" : "Doe",
"Age" : 45,
"Address" : "New York, USA",
"Picture": "base64_string_source_omitted_here"
},
{
"Email" : "peter@smith.com",
"Firstname" : "Peter",
"Lastname" : "Smith",
"Age" : 52,
"Address" : "Paris, France"
},
{
"Email" : "bond@007.com",
"Firstname" : "James",
"Lastname" : "Bond",
"Age" : 35,
"Address" : "Liverpool, UK"
}
]
index.html
先給出完整代碼:
<!DOCTYPE HTML>
<html>
<head>
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta http-equiv='Content-Type' content='text/html;charset=UTF-8'/>
<!-- Please change the file position of sap-ui-cor.js according to environment -->
<script src="../resources/sap-ui-core.js"
id="sap-ui-bootstrap"
data-sap-ui-libs="sap.m, sap.ui.commons, sap.ui.table"
data-sap-ui-xx-bindingSyntax="complex"
data-sap-ui-theme="sap_bluecrystal">
</script>
<script>
jQuery.sap.require("sap.ui.core.util.MockServer");
var currentUser = null;
var sCurrentPath;
// Application Header
var oAppHeader = new sap.ui.commons.ApplicationHeader("appHeader");
oAppHeader.setLogoSrc("http://sap.github.io/openui5/images/icotxt_white_220x72_blue_open.png");
oAppHeader.setDisplayWelcome(false);
oAppHeader.setDisplayLogoff(false);
oAppHeader.placeAt("content");
// Create mock server
var oMockServer = new sap.ui.core.util.MockServer({
rootUri: "http://mymockserver/",
});
oMockServer.simulate("model/metadata.xml", "model/");
oMockServer.start();
// Application data
var oModel = new sap.ui.model.odata.v2.ODataModel("http://mymockserver/", true);
sap.ui.getCore().setModel(oModel);
//-------------------------------------
// Build a form to edit or create user
// mode: 0 for edting, 1 for creating
//------------------------------------
function buildUserForm(mode){
var oSimpleForm = new sap.ui.layout.form.SimpleForm({
content: [
new sap.ui.core.Title({text:"User Information"}),
new sap.ui.commons.Label({text: "Email"}),
new sap.ui.commons.TextField({value: "{Email}", editable: false}),
new sap.ui.commons.Label({text: "First name"}),
new sap.ui.commons.TextField({value: "{Firstname}"}),
new sap.ui.commons.Label({text: "Last name"}),
new sap.ui.commons.TextField({value: "{Lastname}"}),
new sap.ui.commons.Label({text:"Age"}),
new sap.ui.commons.TextField({value: "{Age}"}),
new sap.ui.commons.Label({text:"Address"}),
new sap.ui.commons.TextField({value: "{Address}"}),
new sap.ui.core.Title({text:"Photo"}),
new sap.m.Image({
width: "100px",
src: {
path: "Picture",
formatter: function(sBase64Value){
var sDataUrl = "data:image/bmp;base64," + sBase64Value;
if (sBase64Value){
return sDataUrl;
}else{
return;
}
}
}
})
]
});
// 1 表示新建
if (mode == 1){
var content = oSimpleForm.getContent();
content[2].setEditable(true);
}
if (mode == 0){
oSimpleForm.bindElement(sCurrentPath);
}
return oSimpleForm;
}
//----------------------------------------------------
// CREATE Operation
// Form was open when user press [Create user] button
//----------------------------------------------------
function openCreateDialog(){
var oCreateDialog = new sap.ui.commons.Dialog({
minWidth: "400px"
});
oCreateDialog.setTitle("Create User");
var oSimpleForm = buildUserForm(1); // 1 represent creating
oCreateDialog.addContent(oSimpleForm);
oCreateDialog.addButton(
new sap.ui.commons.Button({
text: "Submit",
press: function() {
var content = oSimpleForm.getContent();
// new entry
var oEntry = {};
oEntry.Email = content[2].getValue();
oEntry.Firstname = content[4].getValue();
oEntry.Lastname = content[6].getValue();
oEntry.Age = content[8].getValue();
oEntry.Address = content[10].getValue();
// Commit creating operation
var oModel = sap.ui.getCore().getModel();
oModel.create("/Users", oEntry, {
success: function(oData, oResponse){
console.log("Response", oResponse);
oCreateDialog.close();
oModel.refresh();
},
error: function(oError){
console.log("Error", oError);
oCreateDialog.close();
}
});
}
})
);
oCreateDialog.open();
};
//-------------------------------------------------
// PUT Operation
// Open dialog when user pressing [Update user' data] button
//-------------------------------------------------
function openUpdateDialog(){
var oUpdateDialog = new sap.ui.commons.Dialog({
minWidth: "600px",
title: "Update user's data"
});
var oSimpleForm = buildUserForm(0);
oUpdateDialog.addContent(oSimpleForm);
oUpdateDialog.addButton(
new sap.ui.commons.Button({
text: "Submit",
press: function() {
var content = oSimpleForm.getContent();
var oEntry = {};
oEntry.Email = content[2].getValue();
oEntry.Firstname = content[4].getValue();
oEntry.Lastname = content[6].getValue();
oEntry.Age = content[8].getValue();
oEntry.Address = content[10].getValue();
oEntry.Picture = "base64_string";
var oModel = sap.ui.getCore().getModel();
var sPath = "/Users('" + oEntry.Email + "')"
oModel.update(sPath, oEntry, {
success: function(oData, oResponse){
console.log("Response", oResponse);
oModel.refresh();
oUpdateDialog.close();
},
error: function(oError){
console.log("Error", oError);
oUpdateDialog.close();
}
});
}
})
);
oUpdateDialog.open();
};
//-----------------------
// DELETE Operation
//-----------------------
function openDeleteDialog(email) {
var oDeleteDialog = new sap.ui.commons.Dialog();
oDeleteDialog.setTitle("Delete User");
var oText = new sap.ui.commons.TextView({text: "Are you sure to delete this user?"});
oDeleteDialog.addContent(oText);
oDeleteDialog.addButton(
new sap.ui.commons.Button({
text: "Confirm",
press:function(){
var oModel = sap.ui.getCore().getModel();
oModel.remove("/Users('" + email + "')", {
success: function(oData, oResponse){
console.log(oResponse);
oModel.refresh();
oDeleteDialog.close();
},
error: function(oError){
console.log("Error", oError);
oDeleteDialog.close();
}
});
}
})
);
oDeleteDialog.open();
}
// Setting up table
var oTable = new sap.ui.table.Table({
editable: false,
selectionMode : sap.ui.table.SelectionMode.Single,
selectionBehavior: sap.ui.table.SelectionBehavior.Row,
rowSelectionChange: function(e) {
var idx = e.getParameter('rowIndex');
if (oTable.isIndexSelected(idx)) {
var cxt = oTable.getContextByIndex(idx);
var path = cxt.sPath;
var obj = oTable.getModel().getProperty(path);
currentUser = obj;
sCurrentPath = path;
//console.log(obj);
}
},
toolbar: new sap.ui.commons.Toolbar({
items: [
new sap.ui.commons.Button({
text: "Create user",
press: function() {
openCreateDialog();
},
}),
new sap.ui.commons.Button({
text: "Update user's data",
press: function() {
var idx = oTable.getSelectedIndex();
if (idx == -1) return;
var rows = oTable.getRows();
var user = rows[idx].getCells();
openUpdateDialog();
},
}),
new sap.ui.commons.Button({
text: "Delete user",
press: function() {
var idx = oTable.getSelectedIndex();
if (idx == -1) return;
var rows = oTable.getRows();
var user = rows[idx].getCells();
openDeleteDialog(user[0].getValue());
},
})
]
}),
});
oTable.addColumn(new sap.ui.table.Column({
label: new sap.ui.commons.Label({text: "Email"}),
template: new sap.ui.commons.TextField().bindProperty("value", "Email"),
editable: false,
sortProperty: "Email"
}));
oTable.addColumn(new sap.ui.table.Column({
label: new sap.ui.commons.Label({text: "First name"}),
template: new sap.ui.commons.TextField().bindProperty("value", "Firstname"),
sortProperty: "Firstname",
editable: false,
}));
oTable.addColumn(new sap.ui.table.Column({
label: new sap.ui.commons.Label({text: "Last name"}),
template: new sap.ui.commons.TextField().bindProperty("value", "Lastname"),
sortProperty: "Lastname",
editable: false,
}));
oTable.addColumn(new sap.ui.table.Column({
label: new sap.ui.commons.Label({text: "Age"}),
template: new sap.ui.commons.TextField().bindProperty("value", "Age"),
sortProperty: "Age",
editable: false,
}));
oTable.addColumn(new sap.ui.table.Column({
label: new sap.ui.commons.Label({text: "Address"}),
template: new sap.ui.commons.TextField().bindProperty("value", "Address"),
sortProperty: "Address",
editable: false,
}));
oTable.setModel(oModel);
oTable.bindRows("/Users");
oTable.placeAt("content");
</script>
</head>
<body class="sapUiBody" role="application">
<div id="content"></div>
</body>
</html>
代碼的要點說明
本例使用
sap.ui.table.Table
來顯示數(shù)據(jù)逊躁,如果不考慮跨平臺似踱,這個 table 的顯示效果和交互性強于sap.m.Table
。注意sap.ui.commons.Textfield
已經(jīng)廢棄稽煤。編輯放在 SimpleForm 中核芽。使用的是數(shù)據(jù)綁定模式。但綁定不適用與 Create酵熙,所以使用 mode (0 表示編輯轧简,1 表示新建),只有在編輯模式下匾二,才進行綁定哮独。
function buildUserForm(mode){
var oSimpleForm = new sap.ui.layout.form.SimpleForm({
content: [
new sap.ui.core.Title({text:"User Information"}),
new sap.ui.commons.Label({text: "Email"}),
new sap.ui.commons.TextField({value: "{Email}", editable: false}),
new sap.ui.commons.Label({text: "First name"}),
new sap.ui.commons.TextField({value: "{Firstname}"}),
new sap.ui.commons.Label({text: "Last name"}),
new sap.ui.commons.TextField({value: "{Lastname}"}),
new sap.ui.commons.Label({text:"Age"}),
new sap.ui.commons.TextField({value: "{Age}"}),
new sap.ui.commons.Label({text:"Address"}),
new sap.ui.commons.TextField({value: "{Address}"}),
new sap.ui.core.Title({text:"Photo"}),
new sap.m.Image({
width: "100px",
src: {
path: "Picture",
formatter: function(sBase64Value){
var sDataUrl = "data:image/bmp;base64," + sBase64Value;
if (sBase64Value){
return sDataUrl;
}else{
return;
}
}
}
})
]
});
// 1 表示新建
if (mode == 1){
var content = oSimpleForm.getContent();
content[2].setEditable(true);
}
if (mode == 0){
oSimpleForm.bindElement(sCurrentPath);
}
return oSimpleForm;
}
- CRUD 執(zhí)行拳芙,使用的是
ODataModel
的create()
,update()
和remove()
Create:
var content = oSimpleForm.getContent();
// new entry
var oEntry = {};
oEntry.Email = content[2].getValue();
oEntry.Firstname = content[4].getValue();
oEntry.Lastname = content[6].getValue();
oEntry.Age = content[8].getValue();
oEntry.Address = content[10].getValue();
// Commit creating operation
var oModel = sap.ui.getCore().getModel();
oModel.create("/Users", oEntry, {
success: function(oData, oResponse){
console.log("Response", oResponse);
oCreateDialog.close();
oModel.refresh();
},
error: function(oError){
console.log("Error", oError);
oCreateDialog.close();
}
});
Update:
var content = oSimpleForm.getContent();
var oEntry = {};
oEntry.Email = content[2].getValue();
oEntry.Firstname = content[4].getValue();
oEntry.Lastname = content[6].getValue();
oEntry.Age = content[8].getValue();
oEntry.Address = content[10].getValue();
oEntry.Picture = "base64String";
var oModel = sap.ui.getCore().getModel();
var sPath = "/Users('" + oEntry.Email + "')"
oModel.update(sPath, oEntry, {
success: function(oData, oResponse){
console.log("Response", oResponse);
oModel.refresh();
oUpdateDialog.close();
},
error: function(oError){
console.log("Error", oError);
oUpdateDialog.close();
}
});
刪除
var oModel = sap.ui.getCore().getModel();
oModel.remove("/Users('" + email + "')", {
success: function(oData, oResponse){
console.log(oResponse);
oModel.refresh();
oDeleteDialog.close();
},
error: function(oError){
console.log("Error", oError);
oDeleteDialog.close();
}
});
最后是 mock server,模擬服務(wù)器皮璧,攔截 http 請求:
jQuery.sap.require("sap.ui.core.util.MockServer");
// Create mock server
var oMockServer = new sap.ui.core.util.MockServer({
rootUri: "http://mymockserver/",
});
oMockServer.simulate("model/metadata.xml", "model/");
oMockServer.start();
數(shù)據(jù)來自 model 文件夾下面的 metadata.xml
舟扎。
源代碼
參考
Upload Image to SAP Gateway and Display Image in UI5 – Using New Fileuploader with SAP Gateway