博客
关于我
SAPUI5 (38) - OData Model 的单向绑定和双向绑定
阅读量:688 次
发布时间:2019-03-17

本文共 7142 字,大约阅读时间需要 23 分钟。

单向绑定和双向绑定概述

所谓的单向绑定 (one-way binding),是指 OData model 与 UI 控件之间在数据绑定时, OData model 中数据的变化会同步反应在 UI 控件中,但 UI 控件数据的变化需要手工提交到 OData model;而双向绑定 (two-way binding),则是指 OData model 和 UI 控件的数据双向同步变化。

OData (v2) model 默认的是 one-way binding。OData model 刚开始只支持单向绑定,后来也支持 two-way binding。

使用 one-way 或者 two-way binding,可以进一步简化客户端代码的编写,同时对 CRUD 过程的控制更加精细。但推荐使用 one-way binding。

单向绑定

我们对上一篇程序代码进行修改,先来看看单向绑定。和上一篇比较,代码的变化集中在 App.controller.js 。首先贴出全部代码:

App.controller.js:

sap.ui.define([	"sap/ui/core/mvc/Controller"], function(Controller) {   	"use strict";	var oModel;	var sCurrentPath;	var sCurrentEmp; // cureent employee	var oEmployeeDialog;	return Controller.extend("zui5_odata_sap_backend_crud.controller.App", {   		onInit: function() {   			oModel = this.getOwnerComponent().getModel();			oModel.setUseBatch(false);			this.getView().setModel(oModel);			oEmployeeDialog = this.buildEmpDialog();		},		// Build employee dialog		// If not exists, create an instance, otherwise, just get it.		buildEmpDialog: function() {   			var oView = this.getView();			var oEmpDialog = oView.byId("employeeDialog");			if (!oEmpDialog) {   				oEmpDialog = sap.ui.xmlfragment(oView.getId(),					"zui5_odata_sap_backend_crud.view.EmployeeDialog");								oView.addDependent(oEmpDialog);				// Attach press event for CancelButton				var oCancelButton = oView.byId("CancelButton");				oCancelButton.attachPress(function() {   					oEmpDialog.close();				});			}			return oEmpDialog;		},		// onCreate event		onCreate: function() {   			var oView = this.getView();			oEmployeeDialog.open();			oEmployeeDialog.setTitle("Create Employee");			oView.byId("EmpId").setEditable(true);			oView.byId("SaveEdit").setVisible(false);			oView.byId("SaveCreate").setVisible(true);			// clear			oView.byId("EmpId").setValue("");			oView.byId("EmpName").setValue("");			oView.byId("EmpAddr").setValue("");			// commit save operation			oView.byId("SaveCreate").attachPress(function() {   				oModel.createEntry("/EmployeeCollection", {   					properties: {   						"Mandt": "100",						"EmpId": oView.byId("EmpId").getValue(),						"EmpName": oView.byId("EmpName").getValue(),						"EmpAddr": oView.byId("EmpAddr").getValue()					}				});				oModel.submitChanges();				sap.m.MessageToast.show("Created Successfully.");				// close dialog				if (oEmployeeDialog) {   					oEmployeeDialog.close();				}			});		},		onEdit: function() {   			// no employee was selected			if (!sCurrentEmp) {   				sap.m.MessageToast.show("No Employee was selected.");				return;			}			var oView = this.getView();			oEmployeeDialog.open();			oEmployeeDialog.setTitle("Edit Employee");			oView.byId("EmpId").setEditable(false);			oView.byId("SaveEdit").setVisible(true);			oView.byId("SaveCreate").setVisible(false);			// Attach save event			oView.byId("SaveEdit").attachPress(function() {   				// changes				var oChanges = {   					"EmpName": oView.byId("EmpName").getValue(),					"EmpAddr": oView.byId("EmpAddr").getValue()				};				oModel.setProperty(sCurrentPath + "/EmpName", oChanges.EmpName);				oModel.setProperty(sCurrentPath + "/EmpAddr", oChanges.EmpAddr);				if (oModel.hasPendingChanges()) {   					oModel.submitChanges();					sap.m.MessageToast.show("Changes were saved successfully.");				}								// close dialog				if (oEmployeeDialog) {   					oEmployeeDialog.close();				}			});		},		// onDelete event		onDelete: function() {   			var that = this;			// no employee was selected			if (!sCurrentEmp) {   				sap.m.MessageToast.show("No Employee was selected.");				return;			}			var oDeleteDialog = new sap.m.Dialog();			oDeleteDialog.setTitle("Deletion");			var oText = new sap.m.Label({   				text: "Are you sure to delete employee [" + sCurrentEmp + "]?"			});			oDeleteDialog.addContent(oText);			oDeleteDialog.addButton(				new sap.m.Button({   					text: "Confirm",					press: function() {   						that.deleteEmployee();						oDeleteDialog.close();					}				})			);			oDeleteDialog.open();		},		// deletion operation		deleteEmployee: function() {   			oModel.remove(sCurrentPath, {   				success: function() {   					sap.m.MessageToast.show("Deletion successful.");				},				error: function(oError) {   					window.console.log("Error", oError);				}			});		},		onItemPress: function(evt) {   			var oContext = evt.getSource().getBindingContext();			sCurrentPath = oContext.getPath();			sCurrentEmp = oContext.getProperty("EmpName");			oEmployeeDialog.bindElement(sCurrentPath);		}	});});

说明一下主要代码的变化:

修改数据

单向绑定时,提交编辑的修改通过 setProperty() 方法将变更提交到 OData model,然后用 submitChanges() 方法将变更提交到数据源。如果想取消修改,则使用 resetChanges() 方法:

var oChanges = {       "EmpName": oView.byId("EmpName").getValue(),    "EmpAddr": oView.byId("EmpAddr").getValue()};oModel.setProperty(sCurrentPath + "/EmpName", oChanges.EmpName);oModel.setProperty(sCurrentPath + "/EmpAddr", oChanges.EmpAddr);if (oModel.hasPendingChanges()) {       oModel.submitChanges();    sap.m.MessageToast.show("Changes were saved successfully.");}

oModel.hasPendingChanges() 确保有变更才将变更提交到数据源。

新增数据

新增数据,使用 ODataModel 的 createEntry() 方法,将新增的数据提交到 OData model,然后使用 submitChanges() 方法将请求队列中提交到数据源。如果想取消新增,使用 deleteCreatedEntry() 方法。

oModel.createEntry("/EmployeeCollection", {    properties: {        "Mandt": "100",        "EmpId": oView.byId("EmpId").getValue(),        "EmpName": oView.byId("EmpName").getValue(),        "EmpAddr": oView.byId("EmpAddr").getValue()    }});oModel.submitChanges();

双向绑定

双向绑定,也涉及到 Edit 及 Create 时候,UI 和 Model 的数据交互。但 UI 和 Model 之间变化自动同步。

1). 在 manifest.json 文件中设置默认的绑定模式:

"sap.ui5": {       ...		"models": {   			"i18n": {   				"type": "sap.ui.model.resource.ResourceModel",				"settings": {   					"bundleName": "zui5_odata_sap_backend_crud.i18n.i18n"				}			},			"": {   				"dataSource": "mainService",				"type": "sap.ui.model.odata.v2.ODataModel",				"settings": {   					"defaultBindingMode": "TwoWay",					"metadataUrlParams": {   						"sap-documentation": "heading"					}				}			}		},		...	}

defaultBindingMode 设置为 TwoWay

2). Edit 不需要使用 setProperty() 方法:

oView.byId("SaveEdit").attachPress(function() {       if (oModel.hasPendingChanges()) {           oModel.submitChanges();        sap.m.MessageToast.show("Changes were saved successfully.");    }        // close dialog    if (oEmployeeDialog) {           oEmployeeDialog.close();    }});

因为是双向绑定的,UI 中如果有数据变化 oModel.hasPendingChanges() 可以自动获得获取,不需要 setProperty()

3). Create 的代码:

oEmployeeDialog.unbindElement();var oContext = oModel.createEntry("/EmployeeCollection", {       properties: {           "Mandt": "100"    }});oEmployeeDialog.setBindingContext(oContext);// commit save operationoView.byId("SaveCreate").attachPress(function() {       if (oView.byId("EmpId").getValue()) {           oModel.submitChanges();        sap.m.MessageToast.show("Created Successfully.");        // close dialog        if (oEmployeeDialog) {               oEmployeeDialog.close();        }    } else {           sap.m.MessageToast.show("Employee Id cannot be blank.");    }});

进入 Dialog 的时候,首先解除与已有数据的绑定,然后使用 createEntry() 方法创建一个新的 context。因为 Mandt 字段在 UI 固定为 100,UI 不用管,所以放在 properties 中。设定 oEmpoyeeDialogbindingContext 后,UI 的修改就自动提交给 Model 了。

源代码

参考资料

转载地址:http://upthz.baihongyu.com/

你可能感兴趣的文章
MySQL 数据类型和属性
查看>>
mysql 敲错命令 想取消怎么办?
查看>>
Mysql 整形列的字节与存储范围
查看>>
mysql 断电数据损坏,无法启动
查看>>
MySQL 日期时间类型的选择
查看>>
Mysql 时间操作(当天,昨天,7天,30天,半年,全年,季度)
查看>>
MySQL 是如何加锁的?
查看>>
MySQL 是怎样运行的 - InnoDB数据页结构
查看>>
mysql 更新子表_mysql 在update中实现子查询的方式
查看>>
MySQL 有什么优点?
查看>>
mysql 权限整理记录
查看>>
mysql 权限登录问题:ERROR 1045 (28000): Access denied for user ‘root‘@‘localhost‘ (using password: YES)
查看>>
MYSQL 查看最大连接数和修改最大连接数
查看>>
MySQL 查看有哪些表
查看>>
mysql 查看锁_阿里/美团/字节面试官必问的Mysql锁机制,你真的明白吗
查看>>
MySql 查询以逗号分隔的字符串的方法(正则)
查看>>
MySQL 查询优化:提速查询效率的13大秘籍(避免使用SELECT 、分页查询的优化、合理使用连接、子查询的优化)(上)
查看>>
mysql 查询数据库所有表的字段信息
查看>>
【Java基础】什么是面向对象?
查看>>
mysql 查询,正数降序排序,负数升序排序
查看>>