Technology Sharing

SAPUI5 Basics 11 - Component Configuration (Component)

2024-07-12

한어Русский языкEnglishFrançaisIndonesianSanskrit日本語DeutschPortuguêsΕλληνικάespañolItalianoSuomalainenLatina

1. Background

Components(Component) is an independent and reusable part in SAPUI5 application.

SAPUI5 provides the following two types of components:

  • Faceless components (class: sap.ui.core.Component): No interface components means nouser interfaceRelated elements, used in scenarios where UI element coding is not required;

  • UI Components (class: sap.ui.core.UICcomponent): UI components are used to represent UI elements on the application interface, such as buttons, as well as corresponding settings and metadata.

Note: You cannot add a "headless component" to a component containerComponent Containermiddle;
sap.ui.core.UICcomponent extends sap.ui.core.Component and adds screen rendering capabilities based on sap.ui.core.Component.

Generally speaking, in an application, a complete component should consist of two parts:Controllerdocument(component .js) and the application description descriptor file (manifest.json)。

The biggest advantage of using components is that packaged components can be flexibly embedded intodifferent组件容器(Component Container)For example, Fiori Launchpad is a component container; during the application testing process, we usually create a component container manually.

Note: When instantiating the component container, the application namespace is specified, and the component container will use this path to find the component controller file.

2. Example

2.1 Define component controller file

The following is an example of a component controller file Component.js:


sap.ui.define([
    "sap/ui/core/UIComponent",
    "sap/ui/model/json/JSONModel"
], function (UIComponent, JSONModel) {
    "use strict";

    return UIComponent.extend("my.namespace.demo.Component", {

        metadata : {
            manifest: "json"
        },

        init : function () {
            // call the init function of the parent
            UIComponent.prototype.init.apply(this, arguments);

            // set data model
            var oData = {
                recipient : {
                    name : "World"
                }
            };
            var oModel = new JSONModel(oData);
            this.setModel(oModel);
        }
    });
});
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28

In this example, we first define a new UI component, and then set the manifest to json in the metadata property, which means that we will use a manifest file in JSON format to define the component's configuration.

Then in the init function, we first call the init function of the parent class, then set the JSON model and set it as the component's model. This model contains a recipient object, which has a name attribute with a value of World.

2.2 Loading Components

After defining the component file, we willindex.jsIn the file, instantiate the component container and load the created component to the page.

Here is an example of an index.js file loading a component:

sap.ui.define([
    "sap/ui/core/ComponentContainer"
], function (ComponentContainer) {
    "use strict";
    new ComponentContainer({
        name: "my.namespace.demo",
        settings : {
            id : "demo"
        },
        async: true
    }).placeAt("content");
});
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12

3. Practice

For the purpose of this blog post, let’s encapsulate all UI elements into a component that is separate from the index.html file.

This way, whenever we access a resource, we will be accessing it relative to the component (and not relative to index.html).

This architectural change makes application loading more flexible compared to the previous static index.html page. For example, it can be directly embedded in a container such as SAP Fiori launchpad.

3.1 Create Component.js file

First, let'swebappAn initialComponent.jsFile, used to store our application settings. When the component is instantiated, SAPUI5 will automatically call the component'sinitFunction. Our component inherits from the base classsap/ui/core/UICcomponent, in the rewritteninitThe init function of the base class should be called first in the method.

The created project file structure is as follows:
insert image description here

The code of Component.js is as follows:

sap.ui.define([
    "sap/ui/core/UIComponent"
], function (UIComponent) {
"use strict";

    return UIComponent.extend("zsapui5.test.Component", {
        init() {
            // call the init function of the parent
            UIComponent.prototype.init.apply(this, arguments);
        }
    });
});
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12

3.2 Add metadata to Component.js

Next, let's add the application configuration to the Component.js file.

The modified Component.js code is as follows:

sap.ui.define([
    "sap/ui/core/UIComponent",
    "sap/ui/model/json/JSONModel",
    "sap/ui/model/resource/ResourceModel"
], function (UIComponent,JSONModel,ResourceModel) {
    "use strict";

    return UIComponent.extend("zsapui5.test.Component", {
        metadata: {
            "interfaces": ["sap.ui.core.IAsyncContentCreation"],
            "rootView": {
                "viewName": "zsapui5.test.view.App",
                "type": "XML",
                "id": "app"
            }
        },

        init() {
            //call  the init function of the parent
            UIComponent.prototype.init.apply(this, arguments);

            //set data model
            const oData = {
                recipient : {
                    name: "World"
                }
            };
            const oModel = new JSONModel(oData);
            this.setModel(oModel);

            //set i18n model
            const i18nModel = new ResourceModel({
                bundleName: "zsapui5.test.i18n.i18n"
            });
            this.setModel(i18nModel, "i18n");
        }
    });
});
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38

The modified component.js file consists of two parts:元数据部分And called when the component is initializedinit函数部分

The metadata section defines the root viewApp.view.xmlThe file references the component so that it can manage the display of the application view instead of directly inindex.jsThe root view is created and displayed directly in the file. The metadata definition also implementssap.ui.core.IAsyncContentCreationInterface that allows components to be created completely asynchronously.

...
        metadata: {
            "interfaces": ["sap.ui.core.IAsyncContentCreation"],
            "rootView": {
                "viewName": "zsapui5.test.view.App",
                "type": "XML",
                "id": "app"
            }
...
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

Note that the sap.ui.core.IAsyncContentCreation interface implicitly sets both the component's rootView and its router configuration to "async": true; We will describe its purpose in a subsequent blog post on "Routing and Navigation".

In the init function, we do the same as before.App.controller.jsInstantiate the data model as done in the controller fileoModeland i18n modeli18nModel

...
        init() {
            //call  the init function of the parent
            UIComponent.prototype.init.apply(this, arguments);

            //set data model
            const oData = {
                recipient : {
                    name: "World"
                }
            };
            const oModel = new JSONModel(oData);
            this.setModel(oModel);

            //set i18n model
            const i18nModel = new ResourceModel({
                bundleName: "zsapui5.test.i18n.i18n"
            });
            this.setModel(i18nModel, "i18n");
        }
...
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21

Please note that the model isBind directly to the componentHowever, since nested controls automatically inherit the model from their parent control, the model is available on the view as well.

3.3 Adjust the App.controller.js file

Since we have already implemented the binding between the data object and the i18n model object in the Component.js file, let's add theApp.controller.jsLogical removal of controller files, i.e. deletion onInit 函数and所需的模块引用
insert image description here

The modified code looks like this:

sap.ui.define([
    "sap/ui/core/mvc/Controller",
    "sap/m/MessageToast"
], function (Controller, MessageToast) {
    "use strict";

    return Controller.extend("zsapui5.test.controller.App", {

        onShowHello: function () {
            // read msg from i18n model
            const oBundle = this.getView().getModel("i18n").getResourceBundle();
            const sRecipient = this.getView().getModel().getProperty("/recipient/name");
            const sMsg = oBundle.getText("helloMsg", [sRecipient]);

            // show message
            MessageToast.show(sMsg);
        }
    });
});
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19

3.4 Adjust the index.js file

In the previous index.js file, we directly instantiated the application's view objectXMLViewNow, let's instantiate the view through the component container.

To do this, we replace the view dependency we added previously with the newsap/ui/core/ComponentContainerDependencies. This component container acts as a parent component for the application component and handles its properties and navigation events.

When creating an instance of a component container, you need to specify the application namespace, i.e.zsapui5.test(It points to the webapp folder of your project, which is where the component.js file is located).

insert image description here

The effect of the adjusted index.js file is as follows:

sap.ui.define([
    "sap/ui/core/ComponentContainer"
], function (ComponentContainer) {
    "use strict";

    new ComponentContainer({
        name: "zsapui5.test",
        settings : {
            id : "test"
        },
        async: true
    }).placeAt("content");
});
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13

3.5 General Agreement

When packaging application components, we should follow the following conventions:

  • The component name is Component .js
  • The component should be located along with all the UI resources of the application inwebappfolder
  • If you want to use the index.html file efficiently, it is also located inwebappIn folder

3.6 Run

Running the adjusted program, the effect is as follows:

insert image description here

The application will run the same as before the adjustment.ctrl + shift + alt + sOpening the Diagnostics window to view the control layout, we can find the following differences.

The newly added ComponentContainer is the parent control of XMLView.
insert image description here

4. Summary

This article introduces the concept and encapsulation of components in SAPUI5 and demonstrates their usage through an example.