Show TOC

Step 9: Component ConfigurationLocate this document in the navigation structure

After we have introduced all three parts of the Model-View-Controller (MVC) concept, we now come to another important structural aspect of SAPUI5. In this step, we will encapsulate all UI assets in a component that is independent from our index.html file. Components are independent and reusable parts used in SAPUI5 applications. Whenever we access resources, we will now do this relatively to the component (instead of relatively to the index.html). This architectural change allows our app to be used in more flexible environments than our static index.html page, such as in a surrounding container like the SAP Fiori launchpad.

Preview
Figure 1: An input field and a description displaying the value of the input field (No visual changes to last step)
Coding
You can view and download all files in the Explored app in the Demo Kit under Walkthrough - Step 9.
Figure 2: Folder Structure for this Step

After this step your project structure will look like the figure above. We will create the Component.js file now and modify the related files in the app.

webapp/Component.js (New)
sap.ui.define([
   "sap/ui/core/UIComponent"
], function (UIComponent) {
   "use strict";
   return UIComponent.extend("", {

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

We create an initial Component.js file in the webapp folder that will hold our application setup. The init function of the component is automatically invoked by SAPUI5 when the component is instantiated. Our component inherits from the base class sap.ui.core.UIComponent and it is obligatory to make the super call to the init function of the base class in the overridden init method.

webapp/Component.js
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("sap.ui.demo.wt.Component", {
            metadata : {
		rootView: "sap.ui.demo.wt.view.App"
	},
      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);

         // set i18n model
         var i18nModel = new ResourceModel({
            bundleName : "sap.ui.demo.wt.i18n.i18n"
         });
         this.setModel(i18nModel, "i18n");
      }
   });
});

The Component.js file consists of two parts now: The new metadata section that simply defines a reference to the root view and the previously introduced init function that is called when the component is initialized. Instead of displaying the root view directly in the index.html file as we did previously, the component will now manage the display of the app view.

In the init function we instantiate our data model and the i18n model like we did before in the app controller. Be aware that the models are directly set on the component and not on the root view of the component. However, as nested controls automatically inherit the models from their parent controls, the models will be available on the view as well.

webapp/controller/App.controller.js
sap.ui.define([
   "sap/ui/core/mvc/Controller",
   "sap/m/MessageToast"
], function (Controller, MessageToast) {
   "use strict";
   return Controller.extend("sap.ui.demo.wt.controller.App", {
      onShowHello : function () {
         // read msg from i18n model
         var oBundle = this.getView().getModel("i18n").getResourceBundle();
         var sRecipient = this.getView().getModel().getProperty("/recipient/name");
         var sMsg = oBundle.getText("helloMsg", [sRecipient]);
         // show message
         MessageToast.show(sMsg);
      }
   });
});

Delete the onIinit function and the required modules; this is now done in the component. You now have the code shown above.

webapp/index.html
<!DOCTYPE html>
<html>
   <head>
      <meta http-equiv="X-UA-Compatible" content="IE=edge">
      <meta charset="utf-8">
      <title>Walkthrough</title>
      <script
         id="sap-ui-bootstrap"
         src="/resources/sap-ui-core.js"
         data-sap-ui-theme="sap_bluecrystal"
         data-sap-ui-libs="sap.m"
         data-sap-ui-bindingSyntax="complex"
         data-sap-ui-compatVersion="edge"
         data-sap-ui-preload="async"
         data-sap-ui-resourceroots='{
            "sap.ui.demo.wt": "./"
         }' >
      </script>
      <script>
         sap.ui.getCore().attachInit(function () {
            new sap.ui.core.ComponentContainer({
               name : "sap.ui.demo.wt"
            }).placeAt("content");

         });
      </script>
   </head>
   <body class="sapUiBody" id="content">
   </body>
</html>

On the index page we now instantiate the component instead of the app view. The helper method sap.ui.core.ComponentContainer instantiates the component by searching for a Component.js file in the namespace that is passed in as an argument. The component automatically loads the root view that we have defined above and displays it. If you now call the index.html file, the app should still look the same, but is now packaged into a UI component.

Conventions
  • The component is named Component.js.

  • Together with all UI assets of the app, the component is located in the webapp folder.

  • The index.html file is located in the webapp folder if it is used productively.