Technology Blogs by Members
Explore a vibrant mix of technical expertise, industry insights, and tech buzz in member blogs covering SAP products, technology, and events. Get in the mix!
cancel
Showing results for 
Search instead for 
Did you mean: 
ThorstenHoefer
Active Contributor

1. Introduction


In forever changing circumstances solutions need to be tailored to address the requirements of specific situations.

Programs also required different gui and code elements dependent on different circumstances.
How therfore does one find the balance between being flexible and specified, if required.

2. Differentiation between products


Products from a list are not always of the same category (for example: food and beverage)

In this blog post, I will demonstrate how to handle different categories of selected products.

The product view controller will load category dependent fragments, including their specified controllers.

To use common method, each fragment controller is connected to the view controller.

The final project structure is shown in the screenshot below


Project structure


At first a JSON List of products is used in the model of below example.
{ 
"products": [
{"kind":"Food", "article":"Meet"}
, {"kind":"Food", "article":"Choclate"}
, {"kind":"Food", "article":"Cookie"}
, {"kind":"Beverage", "article":"Wine"}
, {"kind":"Beverage", "article":"Coke"}
, {"kind":"Beverage", "article":"Beer"}
]
}

These products are bound to the list in the product view
       <List headerText="Products" 
items="{/products}"
itemPress=".onItemPress">
<StandardListItem
title="{article}"
type="Active"/>
</List>

The product view contains additional a placeholder to include the dynamic content for the product category.
<HBox id="detail" class="sapUiLargeMargin"> </HBox>

 

The project includes two different fragments with controller:

  1. Beverage.fragment.xml and Beverage.controller.js

  2. Food.fragment.xml and Food.controller.js


The fragment controllers are referenced in the view controller. The attribute FragCtrl is used to allow dynamic access to the fragment controller class by name.
sap.ui.define([
"sap/ui/core/mvc/Controller",
"sap/ui/core/Fragment",
"sap/m/MessageToast",
"sapui5/module/fragmentCtrl/fragment/Food.controller",
"sapui5/module/fragmentCtrl/fragment/Beverage.controller"
], function (Controller,Fragment,MessageToast, FoodController, BeverageController) {
"use strict";

return Controller.extend("sapui5.module.fragmentCtrl.controller.Product", {
...
FragCtrl : {
Food: FoodController,
Beverage: BeverageController
}

});
});

 

The event 'itemPress' of the product list is connected to the handler 'onItemPress' of the view controller. Method onItemPress determines the selected product, including their property 'kind' (in used example; "Food" or "Beverage").

If the fragment is not already initialized and included as a reference in the array aFragment[], the fragment is loaded with the corresponding controller.

The view controller itself is passed to the constructor of the fragment controller
by the parameter this.

new this.FragCtrl[_sKind](this);

Finally, the fragment is bound to the context of the selected product item, to display the individual product details.

 
    aFragment : [],
onItemPress: function(oEvent){
var _oItem = oEvent.getParameter("listItem");
var _oCtx = _oItem.getBindingContext();
var _sKind = _oCtx.getProperty("kind")
var _sPath = _oCtx.getPath()
var _fragment = this.aFragment[_sKind];
if(!_fragment){
let _oCtrl = new this.FragCtrl[_sKind](this);
_fragment = Fragment.load({
id:"idFragment",
name: "sapui5.module.fragmentCtrl.fragment."+_sKind,
controller: _oCtrl
});
this.aFragment[_sKind] = _fragment;
};
_fragment.then((oFragment)=>{
var _oContainer = this.getView().byId("detail");
_oContainer.removeAllItems();
oFragment.bindElement(_sPath);
_oContainer.addItem(oFragment)
})
}

 

The constructor of both fragment controllers keeps the reference of the view controller in this.vc
sap.ui.define([
"sap/ui/base/Object",
"sap/m/MessageToast",
], function (BaseObject,MessageToast) {
"use strict";

return BaseObject.extend("apui5.module.fragmentCtrl.fragment.Food.controller", {
constructor: function(pViewCtrl){
this.vc = pViewCtrl
},
onClick:function(oEvent){
MessageToast.show("click on Food Controller");
}
});
});

 

Each fragment is specific for the product type, as shown in a simple example for the food fragment.
<core:FragmentDefinition xmlns:core="sap.ui.core"
xmlns="sap.m">
<VBox>
<Title level="H2" text="Welcome to your selected Food"/>
<Text text="{article}"/>
<Button text="which type ?" press=".onClick"/>
<Button text="which view ?" press=".vc.onClick"/>
</VBox>
</core:FragmentDefinition>

The handler for the button 'press' is either in the fragment controller ( .onClick ) or in the view controller ( .vc.onClick )


3. Result


All products are collected in a common list. Dependent on the selection, different fragments are loaded to display the individual product details.

The code for both fragments is being kept separate in different controllers, with a common code base in the product view controller.


Food details with onPress of the fragment controller


 

 


Beverage details with onPress of the fragment controller


 

 


Beverage details with onPress of the product view controller


 

4. Conclusion


Modularization is an efficient method of handling different cases without overloading view and controller with all possible cases.

One of the advantages of this solution is not having to hide the irrelevant fields leaving only the relevant elements displayed,

The main advantage is the extensibility. Fragments can be copied and adjusted for new use cases (eg: new category - cosmetics).

The maintainability is improved by connecting the code close to the fragment.

If you are interested in learning more about sap ui5, please check the UI5 community

I'd like to encourage you to share your knowledge or ask your question with other community members
Labels in this area