MultiModel [Since Neptune DXP - SAP Edition 22]
Limitations
The MultiModel Object is introduced with Neptune DXP - SAP Edition 22. This new Object Type can currently only be used in the SAP GUI Designer. We will also bring this feature to Web App Designer in an upcoming patch.
Technical Concept
In general Neptune DXP - SAP Edition follows the same principles as Neptune DXP - Open Edition when it comes to the way the MultiModel works. The concept of using a MultiModel Object inside your Neptune Applications is a little different compared to the traditional Model Objects. Normally you would assign a "Model Source" to an Application Object to connect this component and its sub-SAP UI5 Components to Data. The Neptune Runtime will then generate not only a Javascript object for the SAPUI5 component itself but also a model javascript object that is being bound to the Control.
Example: This sap.m.Table component in the App Designer will be generated the following way. image::app-designer-multimodel-mt-all-types.png[]
var otabMT_ALL_TYPES = new sap.m.Table("otabMT_ALL_TYPES");
var modelotabMT_ALL_TYPES = new sap.ui.model.json.JSONModel();
otabMT_ALL_TYPES.setModel(modelotabMT_ALL_TYPES);
So there will be a dedicated JSON Model (sap.ui.model.json.JSONModel) for SAPUI5 Components that have a ModelSource assigned
myComponentName.setModel(modelmyComponentName);
Also, note that this approach will set the Model without the optional sName Parameter that would be available in the setModel Method:
Because the model is set without the sName Parameter they will only be accessed relatively in sub SAP UI5 Components.
The MultiModel approach is different.
It is a dedicated object you can insert into your application from the Library Tree (you will find it under the "nep.resources" Folder).
You would then assign a "Model Source" to the MultiModel the same way you would do it to the SAPUI5 Control directly.
Note: You can only assign a "Structure" Type to a MultiModel Object, not an "Array" Type.
The most important fact that differentiates the MultiModel from other Model Objects is the fact that the setModel method is not called on a dedicated SAPUI5 Object but on the Root of the whole Neptune Application with the sName Parameter. In the case of a Neptune Application running Standalone "Root" means:
sap.ui.getCore().setModel(modelObject,"nameOfModelObject")
In the case of a Neptune Application running inside a Fiori-/ Neptune Launchpad or Mobile Client "Root" means:
this.setModel(modelObject,"nameOfModelObject")
// this is a reference to the sap.ui.jsview that runs the Neptune Application
That allows all components inside the Neptune Application to make use of the data inside the Model by addressing it with its name (sName Parameter) as a prefix. So the difference compared to dedicated Model Objects is that you can Reference the Data of a MultiModel from all places inside your Application by prefixing it with its sName.
Example:
This MultiModel Object has a nested ModelSource (structure "MS_FLIGHT_DATA" with Table "CARRIERS" as a component) assigned to it:
The Javascript Code will be generated in the following way:
Neptune App running standalone:
var modeloMMApplCMS_FLIGHT_DATA = new sap.ui.model.json.JSONModel();
sap.ui.getCore().setModel(modeloMMApplCMS_FLIGHT_DATA,"oMMApplCMS_FLIGHT_DATA");
Neptune App running inside a Neptune Launchpad:
var modeloMMApplCMS_FLIGHT_DATA = new sap.ui.model.json.JSONModel();
this.setModel(modeloMMApplCMS_FLIGHT_DATA,"oMMApplCMS_FLIGHT_DATA");
Example for Tables
The MultiModel Object itself is just the Container for the Data. To assign this Data to other SAPUI5 Controls (bind aggregations and Attributes) the MultiModel Object needs to be referenced from those various places.
When you want to use Array typed data from the MultiModel in your SAPUI5 Controls (eg bindAggregation "items" of a sap.m.Table) you would need to assign the "Model Path" targeting the Array inside the MultiModel Object.
The Binding Browser makes it easy to select the corresponding Array.
Example: Clicking on the Binding Button next to the "Model Path" will bring up the Binding Browser only showing MultiModel Sources.
Doubleclicking the "CARRIERS" Table will assign the corresponding Model Path:
The "Model Path" Value will be set accordingly:
You can see that the name of the Model is set as a Prefix to identify which "Root" Model you are addressing.
The generated Javascript for the aggregation will then be like this:
var ocolItemoMT_CARRIERS = new sap.m.ColumnListItem(this.createId("ocolItemoMT_CARRIERS"),{});
otabMT_CARRIERS.bindAggregation("items", "oMMApplCMS_FLIGHT_DATA>/CARRIERS",ocolItemoMT_CARRIERS);
If you then want to bind Properties of the Line Items to corresponding sub components you can again use the Binding Browser to select the desired fields:
Doubleclicking "CARRID" will set the binding accordingly:
Note that the binding in this case again will get the name of the Model set as a prefix. The generated Javascript will also reflect this:
var txtoMT_CARRIERSCARRID = new sap.m.Text(this.createId("txtoMT_CARRIERSCARRID"),
{text:"{oMMApplCMS_FLIGHT_DATA>CARRID}"});
At first, it might be confusing why one would need to add the name of the Model as a prefix since the aggregation already has the relative "Model Path" of the MultiModel but SAP UI5 allows you to bind data from various "Named Models" (models that have been set with the sName Parameter in the setModel Method). So you will always need to specify the Named Model in any Binding case.
Example for (nested) Structures
In cases where you don’t need any aggregations (for example in a Form), the usage of a MultiModel is even more simple.
In this example we have another MultiModel that has a Model Source MS_NESTED that contains a nested Structure:
If you then want to bind a Property of a SAPUI5 Control to an element of the MultiModel you can directly bind it. Again our Binding Browser will give you easy access to the Elements you can bind to:
Doubleclicking "FOO" will set the binding accordingly:
The Binding follows the same pattern. The Name of the MultiModel is set as a prefix followed by the target element (separated by forward slashes).
The generated Javascript Code looks like the following:
var otxtMMMSNESTEDNESTEDFOO = new sap.m.Text(this.createId("otxtMMMSNESTEDNESTEDFOO"),
{text:"{oMMApplCMS_NESTED>/NESTED/FOO}"});
Custom Binding
To be able to address more complex Binding Scenarios we changed the Purpose of the Input Field in our Binding Browser to allow not only Expression Binding (starting with {= … } ) but also plain direct binding.
Example: Having two nested tables we can directly bind to the nested table by providing the index of the surrounding table. image::app-designer-multimodel-cust-binding-mt-carriers.png[]