Odata SAPUI5-将关联/外键更新为产品的另一个类别
我有一个简单的要求,即从SAPUI5客户端应用程序更新给定产品的“类别Id” 我的产品和类别数据库设计为: 类别表包含ID、名称和说明。 产品表具有ID、名称、说明和类别ID。类别ID是类别表的外键,是此表中的必填列 使用CRUD操作实现OData服务。这些操作使用postman和json输入请求进行测试。创建(发布)请求示例: { “名称”:“12月18日的iPad”, “说明”:“2019年12月18日”, "Category@odata.bind“:1} 补丁请求:(用于更新) { “说明”:“笔记本基本型,1.7GHz-15 XGA-1024MB DDR2 SDRAM-40GB-更新版”, "Category@odata.bind“:2} 我正在使用SAPUI5 sap.m.表格显示产品。表的列表绑定在记录(项)发生任何更改时发送自动请求。在此过程中,它只发送不带类别id的产品信息 当我想更改类别id时,这让我很烦恼。比如说,我的表列表绑定是“{/Products}”。 如果我对类别ID使用绑定“{Category/ID}”,它将发送对类别实体的更新请求 我的请求应该是这样的: {“名称”:“名称1”Category@odata.bind“:2} 我们如何在SAPUI5中实现这一点 下面是重要的代码 View.xmlOdata SAPUI5-将关联/外键更新为产品的另一个类别,odata,sapui5,Odata,Sapui5,我有一个简单的要求,即从SAPUI5客户端应用程序更新给定产品的“类别Id” 我的产品和类别数据库设计为: 类别表包含ID、名称和说明。 产品表具有ID、名称、说明和类别ID。类别ID是类别表的外键,是此表中的必填列 使用CRUD操作实现OData服务。这些操作使用postman和json输入请求进行测试。创建(发布)请求示例: { “名称”:“12月18日的iPad”, “说明”:“2019年12月18日”, "Category@odata.bind“:1} 补丁请求:(用于更新) { “说明
<mvc:View
controllerName="sap.ui.core.tutorial.odatav4.controller.ProductsController"
displayBlock="true"
xmlns:core="sap.ui.core"
xmlns="sap.m"
xmlns:mvc="sap.ui.core.mvc">
<VBox>
<items>
<Table
id="productsTable"
growing="true"
growingThreshold="3"
items="{
path: '/Products',
parameters: {
$count: true,
'expand': 'Category'
},
events:{
change: '.onChangeHandler'
}
}"
mode="SingleSelectLeft">
<!-- ,$$updateGroupId : 'peopleGroup' -->
<headerToolbar>
<OverflowToolbar>
<content>
<ToolbarSpacer/>
<SearchField
id="searchField"
width="20%"
placeholder="{i18n>searchFieldPlaceholder}"
enabled="{= !${appView>/hasUIChanges}}"
search=".onSearch"/>
<Button
id="addUserButton"
icon="sap-icon://add"
tooltip="{i18n>createButtonText}"
press=".onCreate">
<layoutData>
<OverflowToolbarLayoutData priority="NeverOverflow"/>
</layoutData>
</Button>
<Button
id="deleteUserButton"
icon="sap-icon://delete"
tooltip="{i18n>deleteButtonText}"
press=".onDelete">
<layoutData>
<OverflowToolbarLayoutData priority="NeverOverflow"/>
</layoutData>
</Button>
<Button
id="refreshUsersButton"
icon="sap-icon://refresh"
enabled="{= !${appView>/hasUIChanges}}"
tooltip="{i18n>refreshButtonText}"
press=".onRefresh"/>
<Button
id="sortUsersButton"
icon="sap-icon://sort"
enabled="{= !${appView>/hasUIChanges}}"
tooltip="{i18n>sortButtonText}"
press=".onSort"/>
</content>
</OverflowToolbar>
</headerToolbar>
<columns>
<Column id="userNameColumn">
<Text text="{i18n>userNameLabelText}"/>
</Column>
<Column id="firstNameColumn">
<Text text="{i18n>firstNameLabelText}"/>
</Column>
<Column id="lastNameColumn">
<Text text="{i18n>lastNameLabelText}"/>
</Column>
<Column id="tierIdColumn">
<Text text="{i18n>tierIdLabelText}"/>
</Column>
<!-- <Column id="tierIdColumn2">
<Text text="Category Id placeholder" />
</Column> -->
</columns>
<items>
<ColumnListItem id="table_col">
<cells>
<Input
value="{ID}"
valueLiveUpdate="true"
liveChange=".onInputChange"/>
</cells>
<cells>
<Input
value="{Name}"
liveChange=".onInputChange"/>
</cells>
<cells>
<Input
value="{Description}"
liveChange=".onInputChange"/>
</cells>
<cells>
<Input value="{Category/ID}" liveChange=".onInputChange"/>
</cells>
</ColumnListItem>
</items>
</Table>
<!-- <footer> -->
<Toolbar visible="{appView>/hasUIChanges}">
<ToolbarSpacer/>
<Button
id="saveButton"
type="Emphasized"
text="{i18n>saveButtonText}"
enabled="{= ${message>/}.length === 0 && ${appView>/usernameEmpty} === false }"
press=".onSave"/>
<Button
id="doneButton"
text="{i18n>cancelButtonText}"
press=".onResetChanges"/>
</Toolbar>
<!-- </footer> -->
</items>
</VBox>
</mvc:View>
它在SAPUI5中不受支持还是一项特殊要求?在SAPUI5中不受支持还是一项特殊要求?
sap.ui.define([
"sap/ui/core/mvc/Controller",
"sap/m/MessageToast",
"sap/m/MessageBox",
"sap/ui/model/Sorter",
"sap/ui/model/Filter",
"sap/ui/model/FilterOperator",
"sap/ui/model/FilterType",
"sap/ui/model/json/JSONModel",
"sap/base/Log"
], function (Controller, MessageToast, MessageBox, Sorter, Filter, FilterOperator, FilterType, JSONModel, Log) {
"use strict";
var CATEGORIES_TABLE_ID = "productsTable";
return Controller.extend("sap.ui.core.tutorial.odatav4.controller.ProductsController", {
/**
* Hook for initializing the controller
*/
onInit : function () {
var oMessageManager = sap.ui.getCore().getMessageManager(),
oMessageModel = oMessageManager.getMessageModel(),
oMessageModelBinding = oMessageModel.bindList("/", undefined, [],
new Filter("technical", FilterOperator.EQ, true)),
oViewModel = new JSONModel({
busy : false,
hasUIChanges : false,
usernameEmpty : true,
order : 0
});
this.getView().setModel(oViewModel, "appView");
this.getView().setModel(oMessageModel, "message_layers");
oMessageModelBinding.attachChange(this.onMessageBindingChange, this);
this._bTechnicalErrors = false;
// Can I attach an event listener to include category_id before submit
},
/* =========================================================== */
/* begin: event handlers */
/* =========================================================== */
onChangeHandler: function(oEvent){
var eventName = oEvent.getParameter("reason");
console.log("Change: Event raised: " + eventName + ", timestamp = " + new Date().getTime());
},
/**
* Create a new entry.
*/
onCreate : function () {
var oList = this.byId( CATEGORIES_TABLE_ID );
var oBinding = oList.getBinding("items"),
// Create a new entry through the table's list binding
oContext = oBinding.create({
"ID" : null,
"Name" : "",
"Description" : "",
"Category@odata.bind": 1
});
this._setUIChanges(true);
this.getView().getModel("appView").setProperty("/usernameEmpty", true);
// Select and focus the table row that contains the newly created entry
oList.getItems().some(function (oItem) {
if (oItem.getBindingContext() === oContext) {
oItem.focus();
oItem.setSelected(true);
return true;
}
});
},
/**
* Delete an entry.
*/
onDelete : function () {
var oSelected = this.byId( CATEGORIES_TABLE_ID ).getSelectedItem();
if (oSelected) {
oSelected.getBindingContext().delete("$direct").then(function () {
MessageToast.show(this._getText("deletionSuccessMessage"));
}.bind(this), function (oError) {
MessageBox.error(oError.message);
});
}
},
/**
* Lock UI when changing data in the input controls
* @param {sap.ui.base.Event} oEvt - Event data
*/
onInputChange : function (oEvt) {
if (oEvt.getParameter("escPressed")) {
this._setUIChanges();
} else {
this._setUIChanges(true);
// Check if the id in the changed table row is empty and set the appView property accordingly
if (oEvt.getSource().getParent().getBindingContext().getProperty("ID")) {
this.getView().getModel("appView").setProperty("/usernameEmpty", false);
}
}
},
/**
* Refresh the data.
*/
onRefresh : function () {
var oBinding = this.byId( CATEGORIES_TABLE_ID ).getBinding("items");
if (oBinding.hasPendingChanges()) {
MessageBox.error(this._getText("refreshNotPossibleMessage"));
return;
}
oBinding.refresh();
MessageToast.show(this._getText("refreshSuccessMessage"));
},
/**
* Reset any unsaved changes.
*/
onResetChanges : function () {
this.byId( CATEGORIES_TABLE_ID ).getBinding("items").resetChanges();
this._bTechnicalErrors = false; // If there were technical errors, cancelling changes resets them.
this._setUIChanges(false);
},
/**
* Reset the data source.
*/
onResetDataSource : function () {
var oModel = this.getView().getModel(),
oOperation = oModel.bindContext("/ResetDataSource(...)");
oOperation.execute().then(function () {
oModel.refresh();
MessageToast.show(this._getText("sourceResetSuccessMessage"));
}.bind(this), function (oError) {
MessageBox.error(oError.message);
}
);
},
/**
* Save changes to the source.
*/
onSave : function () {
var fnSuccess = function () {
this._setBusy(false);
MessageToast.show(this._getText("changesSentMessage"));
this._setUIChanges(false);
}.bind(this);
var fnError = function (oError) {
this._setBusy(false);
this._setUIChanges(false);
MessageBox.error(oError.message);
}.bind(this);
this._setBusy(true); // Lock UI until submitBatch is resolved.
this.getView().getModel().submitBatch("peopleGroup").then(fnSuccess, fnError);
this._bTechnicalErrors = false; // If there were technical errors, a new save resets them.
},
/**
* Search for the term in the search field.
*/
onSearch : function () {
var oView = this.getView(),
sValue = oView.byId("searchField").getValue(),
oFilter = new Filter("description", FilterOperator.Contains, sValue);
oView.byId( CATEGORIES_TABLE_ID ).getBinding("items").filter(oFilter, FilterType.Application);
},
/**
* Sort the table according to the Description.
* Cycles between the three sorting states "none", "ascending" and "descending"
*/
onSort : function () {
var oView = this.getView(),
aStates = [undefined, "asc", "desc"],
aStateTextIds = ["sortNone", "sortAscending", "sortDescending"],
sMessage,
iOrder = oView.getModel("appView").getProperty("/order");
// Cycle between the states
iOrder = (iOrder + 1) % aStates.length;
var sOrder = aStates[iOrder];
oView.getModel("appView").setProperty("/order", iOrder);
oView.byId( CATEGORIES_TABLE_ID ).getBinding("items").sort(sOrder && new Sorter("description", sOrder === "desc"));
sMessage = this._getText("sortMessage", [this._getText(aStateTextIds[iOrder])]);
MessageToast.show(sMessage);
},
onMessageBindingChange : function (oEvent) {
var aContexts = oEvent.getSource().getContexts(),
aMessages,
bMessageOpen = false;
if (bMessageOpen || !aContexts.length) {
return;
}
// Extract and remove the technical messages
aMessages = aContexts.map(function (oContext) {
return oContext.getObject();
});
sap.ui.getCore().getMessageManager().removeMessages(aMessages);
this._setUIChanges(true);
this._bTechnicalErrors = true;
MessageBox.error(aMessages[0].message, {
id : "serviceErrorMessageBox",
onClose : function () {
bMessageOpen = false;
}
});
bMessageOpen = true;
},
fnFormatter: function(text, key) {
var sText = "";
if (text && key) {
sText += (text + " (" + key + ")");
} else if (text) {
sText += text;
} else if (key) {
sText += key;
}
return sText;
},
/* =========================================================== */
/* end: event handlers */
/* =========================================================== */
/**
* Convenience method for retrieving a translatable text.
* @param {string} sTextId - the ID of the text to be retrieved.
* @param {Array} [aArgs] - optional array of texts for placeholders.
* @returns {string} the text belonging to the given ID.
*/
_getText : function (sTextId, aArgs) {
return this.getView().getModel("i18n").getResourceBundle().getText(sTextId, aArgs);
},
/**
* Set hasUIChanges flag in View Model
* @param {boolean} [bHasUIChanges] - set or clear hasUIChanges
* if bHasUIChanges is not set, the hasPendingChanges-function of the OdataV4 model determines the result
*/
_setUIChanges : function (bHasUIChanges) {
if (this._bTechnicalErrors) {
// If there is currently a technical error, then force 'true'.
bHasUIChanges = true;
} else if (bHasUIChanges === undefined) {
bHasUIChanges = this.getView().getModel().hasPendingChanges();
}
var oModel = this.getView().getModel("appView");
oModel.setProperty("/hasUIChanges", bHasUIChanges);
},
/**
* Set busy flag in View Model
* @param {boolean} bIsBusy - set or clear busy
*/
_setBusy : function (bIsBusy) {
var oModel = this.getView().getModel("appView");
oModel.setProperty("/busy", bIsBusy);
}
,onSelect: function(oEvt){
var selectedCategoryId = oEvt.getSource().getSelectedKey();
this.byId("category_id_4_product").setValue( selectedCategoryId );
},
/**
* Copies category_id value from placeholder column to actual column
*/
_copyToInputField: function( oCells, value ){
for( var i=0; i < oCells.length; i++ ){
if( oCells[i].getId().match( "category_id_actual" ) ){
oCells[i].setValue( value );
}
}
}
});
});
{
"_version": "1.12.0",
"sap.app": {
"id": "sap.ui.core.tutorial.odatav4",
"type": "application",
"i18n": "i18n/i18n.properties",
"applicationVersion": {
"version": "1.0.0"
},
"title": "{{appTitle}}",
"description": "{{appDescription}}",
"dataSources": {
"default": {
"uri": "/DemoService/DemoService.svc/",
"type": "OData",
"settings": {
"odataVersion": "4.0"
}
}
}
},
"sap.ui": {
"technology": "UI5",
"deviceTypes": {
"desktop": true,
"tablet": true,
"phone": true
}
},
"sap.ui5": {
"rootView": {
"viewName": "sap.ui.core.tutorial.odatav4.view.App",
"type": "XML",
"async": true,
"id": "appView"
},
"dependencies": {
"minUI5Version": "1.48.0",
"libs": {
"sap.m": {},
"sap.ui.core": {},
"sap.ui.layout": {}
}
},
"contentDensities": {
"compact": true,
"cozy": true
},
"handleValidation": true,
"models": {
"i18n": {
"type": "sap.ui.model.resource.ResourceModel",
"settings": {
"bundleName": "sap.ui.core.tutorial.odatav4.i18n.i18n"
}
},
"": {
"dataSource": "default",
"settings": {
"autoExpandSelect": true,
"operationMode": "Server",
"groupId": "$direct",
"synchronizationMode": "None"
}
}
}
}
}