Skip to content

Instantly share code, notes, and snippets.

@ricma

ricma/.gitignore Secret

Last active January 4, 2016 19:59
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ricma/a177f8623ceee2aa9dcb to your computer and use it in GitHub Desktop.
Save ricma/a177f8623ceee2aa9dcb to your computer and use it in GitHub Desktop.
Question regarding binding between several models in sapui5, see this question: http://scn.sap.com/thread/3492009
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta http-equiv="Content-Type" content="text/html;charset=UTF-8"/>
<title>Inter-Model bindings in SAPUI5</title>
<script id="sap-ui-bootstrap"
src="https://sapui5.hana.ondemand.com/resources/sap-ui-core.js"
data-sap-ui-theme="sap_goldreflection"
data-sap-ui-libs="sap.ui.commons"></script>
<!-- include requirements -->
<script type="text/javascript" src="ModelConnector.js">
</script>
<script type="text/javascript" src="interModelBindingExample.js">
</script>
<body class="sapUiBody">
<div id="content"></div>
</body>
// Try to bind two models together
// --------------------------------------------------------------------
// Model definition
// Assume this is the master data we want to use in a different model
var oModelA = new sap.ui.model.json.JSONModel({
"dataInA": [
{ "name": "1st @ A" },
{ "name": "2nd @ A" }]});
// Assume this is a view onto the above data
var oModelB = new sap.ui.model.json.JSONModel({
"globalName": "?????"});
// I would like to bind in a TwoWay kind of way
// (oModelB, "/globalName") <---to---> (oModelA, "/dataInA/0/name")
// ...
var oConnector = new ModelConnector(
{oModel: oModelA, sPath: "/dataInA/0/name"},
{oModel: oModelB, sPath: "/globalName"});
// --------------------------------------------------------------------
// view definition
// ... and use this binding in some controls
var oSimpleForm = new sap.ui.layout.form.SimpleForm({
maxContainerCols: 1,
content: [
// --------------------------------------------------
new sap.ui.commons.Label({text:"Value in Model A"}),
new sap.ui.commons.TextField({
width: "20%", value: "{A>/dataInA/0/name}"}),
// --------------------------------------------------
new sap.ui.commons.Label({text:"Value in Model B"}),
new sap.ui.commons.TextField({
width: "20%", value: "{B>/globalName}"}),
// --------------------------------------------------
new sap.ui.commons.Label({text:"Model A"}),
new sap.ui.commons.TextField({
width: "60%", editable: false,
value: {
path: "A>/",
formatter: function(oData) {
return JSON.stringify(oData);
}}}),
// --------------------------------------------------
new sap.ui.commons.Label({text:"Model B"}),
new sap.ui.commons.TextField({
width: "60%", editable: false,
value: {
path: "B>/",
formatter: function(oData) {
return JSON.stringify(oData);
}}})
// --------------------------------------------------
]}).
setModel(oModelA, "A").
setModel(oModelB, "B").
placeAt("content");
/**
* BindingInfo.sModelName // for internal use, defaults to "__modelA"
* BindingInfo.sPath // path in the model to keep in sync,
* // defaults to "" (FIXME: does this work?)
* BindingInfo.oModel // the model to bind
*
* At the end the value of A is initially put into the model B.
*/
// Not working here as we use ondemand.com's resources
//jQuery.sap.declare("ModelConnector");
function ModelConnector(BindingInfoA, BindingInfoB) {
var oConnector = this;
// set default values to the input
this.InfoA = BindingInfoA;
this.InfoA.sModelName = this.InfoA.sModelName || "__modelA";
this.InfoA.sPath = this.InfoA.sPath || "";
this.InfoB = BindingInfoB;
this.InfoB.sModelName = this.InfoB.sModelName || "__modelB";
this.InfoB.sPath = this.InfoB.sPath || "";
// create a control having both models
// FIXME: I expected sap.ui.core.Element to work - which did not,
// even sap.ui.core.Control did not ... therefore using an empty
// textfield
this.oConnection = new sap.ui.commons.TextField();
// set the models
this.oConnection.setModel(this.InfoA.oModel, this.InfoA.sModelName);
this.oConnection.setModel(this.InfoB.oModel, this.InfoB.sModelName);
// set custom data referencing the sub parts of the models
var oCustomDataA = new sap.ui.core.CustomData({
key: this.InfoA.sModelName + "-data",
value: "{" + this.InfoA.sModelName + ">" +
this.InfoA.sPath + "}"});
var oCustomDataB = new sap.ui.core.CustomData({
key: this.InfoB.sModelName + "-data",
value: "{" + this.InfoB.sModelName + ">" +
this.InfoB.sPath + "}"});
// add to the connection element
this.oConnection.addCustomData(oCustomDataA);
this.oConnection.addCustomData(oCustomDataB);
// get the binding objects of the values of the custom data
var oPropertyBindingA = oCustomDataA.getBinding("value");
var oPropertyBindingB = oCustomDataB.getBinding("value");
// cross-connect their change events
oPropertyBindingA.attachChange(function(oChangeEvent) {
oPropertyBindingB.setValue(
oPropertyBindingA.getValue());
// FIXME: also trigger a complete refresh of the model in
// order to have controls updated which are refering to larger
// parts of the model
});
oPropertyBindingB.attachChange(function(oChangeEvent) {
oPropertyBindingA.setValue(
oPropertyBindingB.getValue());
// FIXME: also trigger a complete refresh of the model in
// order to have controls updated which are refering to larger
// parts of the model
});
// trigger an initial change
oPropertyBindingB.setValue(oPropertyBindingA.getValue());
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment