Programming

A Look at SAPUI5 Control Structure

Each control in SAPUI5 has the same code structure. This structure is shown in the skeleton code below.

 

sap.ui.define([

   "sap/ui/core/Control"

], function (Control) {

   "use strict";

return Control.extend("sapui5.demo.mvcapp.controls.myCustomInput", {

     metadata : {

     },

     init : function () {

     },

     onBeforeRendering : function(){

     },

     onAfterRendering : function(){

     },

     exit: function() {

     },

     renderer : function (oRM, oControl) {

     }

   })

});

 

You can see that controls make use of the define syntax. In the first part, all dependencies are declared. The array parameter for the dependencies contains at least the basic control class from SAPUI5, sap.ui.core.Control. This base class is extended here to create a new control.

 

Note that controls can also be based on other existing controls, which can be extended. In such a case, the control that’s extended needs to be loaded as a dependency instead of sap.ui.core.Control.

 

In the following sections, we’ll start with the definition of the control metadata, which forms the application programming interface (API). Then, we’ll turn to the behavior implementation of the control. Last, we’ll create the functionality that will render the control into the Document Object Model (DOM).

 

Metadata

In the second parameter of the define call, you’ll see a factory function. In this case, it extends a control instead of a controller. The factory function creates the constructor for the control and returns this constructor. Here, we find the metadata for the control, in which all the properties and aggregations are declared. The metadata defines the API of the control and can contain properties, aggregations and associations, and events fired by the control.

 

When you design an API, you should consider how properties and aggregations are named, their types, and their default values. This is one of the most important technical parts of designing a control. As soon as you’ve published a control and its API, and more than one application is using it, it’s hard to change anything about the API again without causing regressions and potentially breaking applications. You can look at existing controls—for instance, in the sap.m library—to get a feel for how APIs are designed there.

Properties

A property definition consists of a name, type, and default value, if desired. For a simple text property, which we’ll call myProperty of the type string, the metadata will look like this:

 

metadata : {

     properties : {

         "myProperty": {

     type: "string",

   defaultValue: "your default value goes here"}

   }

}

 

If you don’t need a default value or any further settings, you can also simply assign a type to the name of the property:

 

metadata : {

   properties : {

       "myProperty": "string"

   }

}

 

You can also use SAPUI5-specific types here:

 

metadata : {

   properties : {

       "myCSSProperty": {

            type : "sap.ui.core.CSSSize",

               defaultValue : '100%'},

           }

       }

}

Aggregations

Complex controls can be parents for other controls. These controls are usually aggregated into the parent control. To define such aggregations for child controls, you need to extend the metadata as highlighted in this listing.

 

metadata : {

   properties : {

      "myProperty": "string"

   },

   aggregations : {

      content : {type : "sap.ui.core.Control", multiple : true, singularName : "content"}

   }

}

10

Aggregation definitions again consist of an aggregation name and a type, which is either a particular control or the core control class if every control type is accepted.

 

The multiple parameter determines what relationship the aggregation has to its parent. If it’s set to true, the relationship is of type 0..n, which means an arbitrary number of children can be aggregated. If it’s set to false, the result is a 0..1 relationship, so there can be never more than one control in this aggregation.

 

Aggregated controls take part in the lifecycle of their parents. Aggregations will be instantiated and destroyed along with their parents. Due to this fact, a particular control instance can never be in more than one aggregation at a time.

 

The parameter singularName is optional. The sap.ui.core.Control class inherits from sap.ui.base.ManagedObject. From this parent, it gets functionality such as all the getter and setter methods for properties, aggregations, and associations. These getters and setters are usually typed, meaning, methods are created for each property that will contain the property name. A property with the name sampleProperty will automatically have a getter method named getSampleProperty and a setter named setSampleProperty.

 

The same holds true for aggregations, except that the aggregation name is usually transformed into a plural form for the getter method if the aggregation allows for multiple children. When you name your aggregation in the definition, it’s conventional to specify the name as singular, even if multiple children are expected:

 

listItem : {type : "sap.ui.core.Control", multiple : true}

 

This will result in a getter named getListItems.

 

If you don’t want to have the plural form of your aggregation name in the getter method because you’re using a name that doesn’t allow for it—such as content—you need to set the singularName parameter and specify explicitly which name to use for the getter method.

 

In the case of the content aggregation definition, we’ll have a getter method called getContent, as expected.

Default Aggregations

If you want to omit the aggregation tag in an XML view, you can specify a default aggregation that child controls should go into automatically if no other target aggregation is specified in the view.

 

A default aggregation needs to be defined in the control metadata, as highlighted below.

 

metadata : {

   properties: {

   [...]

   },

   defaultAggregation : "content",

   aggregations : {

     content : {type : "sap.ui.core.Control", multiple : true, singularName : "content"}

   }

[...]

Associations

Remember that associations create a relationship between two controls that are otherwise independent from each other. They don’t share a lifecycle, so if one is instantiated or destroyed, the associated control might not be. An aggregation stores the reference to the child control’s instance, whereas an association only stores the ID. Associations can be defined as controls similarly to aggregations:

 

associations : {

myAssociationName: {type : "sap.ui.core.Control", multiple : false}

}

 

You can also define a singularName parameter, as you would do for aggregations.

Events

Events fired by a control you’re implementing also need to be specified in the metadata so that applications can attach to or detach from them. As with the getters and setters for properties, aggregations, and associations, the named attach and detach methods are automatically generated for you by the framework. In the metadata, events are defined as follows:

 

events : {

press : {}

}

10

Mostly, events are just specified as empty objects. You can also specify an optional allowPreventDefault parameter if you want to give the application the ability to cancel the event. In that case, the metadata for the event would look like this:

 

events : {

press : {"allowPreventDefault" : true}

}

 

However, abstract controls currently are rather static and only consist of elements; they have no behavior and don’t fire any events.

 

Control Behavior

The control behavior consists of the implementation of the lifecycle methods as needed and any additional methods you want to define for the control functionality, including event handlers. All lifecycle methods don’t necessarily need to be implemented for each control. It’s up to you as the developer to decide which of the methods mentioned ahead are required.

 

The control lifecycle provides some hooks that allow you to define what should happen at certain lifecycle phases of the control. For the control, you can implement methods corresponding to these lifecycle hooks.

 

In the init method of the control, the control constructor—everything necessary for the control to do its work—is initialized. This method is called only once, when the control is instantiated.

 

The onBeforeRendering method will be called every time the control is (re-)rendered. Any functionality you want to include to prepare the output properly goes in here. For example, sap.m.Dialog uses this lifecycle hook to determine whether it needs to display its own scroll bar or if its content is scrollable itself. Because this information isn’t available in the init phase, this is the only hook in which checking for this content feature is possible.

 

In the onAfterRendering method, which will be called after each (re-)rendering of a control, the control has already been rendered and is therefore also already part of your application’s DOM. This can be an important phase if you want to run animations, for instance, which rely on a DOM reference for the control.

 

Finally, in the exit method, you can do all kinds of cleanup work. This method is invoked when the control is destroyed, and it should take with it all resources no longer required by your application. If you have any resources in your control that aren’t managed by SAPUI5, you should destroy them here.

 

Control Rendering

The renderer method tells the RenderManager at the core how it should be displayed on screen. This is where you tell SAPUI5 what information and what DOM elements to create in the browser. This is a static method that gets the control instance itself and the global RenderManager instance passed in.

 

For RenderManager, there are some predefined methods to use for the renderer implementation.

 

Now that you know about the structure of a control, you can tap into the real world and create a control.

 

Editor’s note: This post has been adapted from a section of the book SAPUI5: The Comprehensive Guide by Paul Modderman, Christiane Goebels, Denise Nepraunig, and Thilo Seidel.

Recommendation

SAPUI5: The Comprehensive Guide
SAPUI5: The Comprehensive Guide

Your comprehensive guide to SAPUI5! From to , get the know-how to develop MVC apps, use OData, create data bindings, debug and test code, and deploy apps. Learn the dos and don’ts of SAPUI5 and everything in between, whether you’re implementing CRUD operations or writing your own controls. See what’s new with SAP Cloud Platform, SAPUI5 support assistant, and more. Your best apps are yet to come.

Learn More
SAP PRESS
by SAP PRESS

SAP PRESS is the world's leading SAP publisher, with books on ABAP, SAP S/4HANA, SAP CX, intelligent technologies, SAP Business Technology Platform, and more!

Comments