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: 
SureshRa
Active Participant

Purpose


The purpose of this blog is to show how to develop a reuse component using Business Application Studio or VS Code. I also browsed through the earlier blogs on this topic and found it would be better to also align with latest SAP documentation Developing Reuse Components. I suggest the readers go through this SAP documentation and get to know about the basics. I am planning to write two separate blogs:

  1. Develop Reuse Component

  2. Consume Reuse Component


Application vs Reuse Component


The reuse components implement common functionality and are used in many applications. They are consumed in a component container. Any SAPUI5 application component can also be consumed in a component container. However there are differences which make the reuse component the right choice for developing reusable components across many applications.

  • The reuse component is of type 'Library' while the application component is of type 'Application'.

  • The reuse component always runs within a component container whereas the application component can also run in Fiori Launchpad.

  • The reuse component can define (API) properties on its own. These properties can be used to communicate with the application that embeds the reuse component. While the application component can have start-up parameters, they are not API properties.

  • The unnamed model (the OData model) and a JSON model named 'ui' that are defined in the application are propagated to the reuse component. This is not the case in application component. The propagation of the unnamed model is especially important if the data that is accessed by the reuse component is provided by the same OData service that is used by the embedding application.

  • The reuse components contains pre-defined properties and methods that the Fiori Elements Framework calls at various stages. e.g. UI Mode (create, edit, etc.), Area visibility of the reuse component in the Object Page, etc. These properties and methods makes the reuse component much more robust than simply using an application component inside a component container.

  • The reuse component can respond to change events like change in binding context of the embedding page, embedding page binding is forced to refresh and the key information of the embedding page has changed.


Preview


Before we get into details, I just want to give a view of the end result of this demo, which includes consuming application (details to follow in the next blog) and the reuse component. In my demo, the reuse component just displays details of the customer which is inputted in the consuming application.


Demo Preview



Preparing the Project


Create a freestyle application, starting with an empty page using 'Basic' template. I'm using Northwind Data Service for this demo and keeping the view name as "View1". Once your project files are fully generated, make the following changes:

Changes to manifest.json



  • Change the type in sap.app to "library".

  • In the sap.ui5 -> models, we should not have any unnamed model. I just name it e.g. "northwind". This is essential keeping in mind the model propagation of unnamed model from the embedding page.

  • Change the sap.ui5 -> "rootView" to "View1" instead of "App".


Changes to Component.js


We need to add the ExtensionAPI/ReuseComponentSupport to the AMD and the metadata has to be added with all the standard and additional attributes as shown below.
sap.ui.define([
"sap/ui/core/UIComponent",
"sap/suite/ui/generic/template/extensionAPI/ReuseComponentSupport"
],
function (UIComponent, ReuseComponentSupport) {
"use strict";

return UIComponent.extend("demo.suresh.reusecomp.Component", {
metadata: {
manifest: "json",
library: "demoLibrary",
properties: {
/* Standard properties for reuse components */
uiMode: {
type: "string",
group: "standard"
},
semanticObject: {
type: "string",
group: "standard"
},
stIsAreaVisible: {
type: "boolean",
group: "standard"
},
/* Component specific properties */
customerID: {
type: "string",
group: "specific",
defaultValue: ""
}

}
},

init: function () {
//Transform this component into a reuse component for smart templates:
ReuseComponentSupport.mixInto(this);
//Defensive call of init of the super class:
( UIComponent.prototype.init || jQuery.noop ).apply(this, arguments);
}
});
}
);

In addition to above, I also over-ride the setter of the standard attribute stIsAreaVisible and custom attribute customerID to refresh the binding of the view in reuse component.
setStIsAreaVisible: function (bIsAreaVisible) {
if (bIsAreaVisible !== this.getStIsAreaVisible()) {
this.setProperty("stIsAreaVisible", bIsAreaVisible);
}
},

setCustomerID: function (sCustomerID) {
if(sCustomerID !== this.getCustomerID()){
this.setProperty("customerID", sCustomerID);
this.getStIsAreaVisible () &&
this.getModel("northwind").metadataLoaded().then(this._setViewBinding.bind(this,sCustomerID));
}
},

The _setViewBinding is just binding the specific Customer entity to the view
_setViewBinding: function (sCustomerID) {
var oModel = this.getModel("northwind");
this._bindingPath = oModel.createKey("/Customers", {
CustomerID: sCustomerID
});
if (this._compView) {
this._compView.bindElement(this._bindingPath,{model:"northwind"});
}
}

Changes to the View Controller


As the initialisation of the component happens the first time when the consuming application initiates it, we need to ensure the view binding in the "init" method of the view controller also.
onInit: function () {
this.getView().bindElement(this.getOwnerComponent().getBindingPath(),{model:"northwind"});
this.getOwnerComponent().setView(this.getView());
}

Changes to the View



  • In the View1.view.xml, remove the "Page" and "content" tags. All your controls should be directly under mvc:View. I just used a simple form in my view.


<mvc:View id="reuseCompView"
controllerName="demo.suresh.reusecomp.controller.View1"
xmlns:mvc="sap.ui.core.mvc" displayBlock="true"
xmlns="sap.m"
xmlns:f="sap.ui.layout.form">
<VBox id="vboxReuseComp">
<f:SimpleForm id="sfCustomerData"
editable="false"
layout="ResponsiveLayout"
title="Customer (Reuse Component)" >
<f:content>
<Label id="lblCustomerID" text="Customer ID"/>
<Text id="txtCustomerID" text="{CustomerID}" />
<Label id="lblCompanyName" text="Company Name" />
<Text id="txtCompanyName" text="{CompanyName}" />
<Label id="lblAddress" text="Address" />
<Text id="txtAddress" text="{Address}"/>
<Label id="lblRegion" text="Region"/>
<Text id="txtRegion" text="{Region}"/>
<Label id="lblCountry" text="Country"/>
<Text id="txtCountry" text="{Country}"/>
</f:content>
</f:SimpleForm>
</VBox>
</mvc:View>

If you want to create the content dynamically, you can implement the hook method createContent. In that case the Component should also implement interface sap.ui.core.IAsyncContentCreation

Conclusion


That is it. Our reuse component is ready to be consumed. Before we deploy, we can quickly create a consuming application and test it in the local IDE (BAS) itself. I'll cover the consuming application in the next blog.

A reuse component that can be used within a SAP Fiori elements-based application cannot be used in a freestyle application. Provide two separate components that refer to a common implementation. A good reference of this concept is the standard SAP Attachment Reuse-Component (BSP artefact PLM_ATH_CRES1).
2 Comments
MarceloRSilva
Participant
Thanks Suresh! Well written with clear instructions and examples.
SureshRa
Active Participant
0 Kudos
Thanks Marcelo.
Labels in this area