Search code examples
sapui5

Is there a way to get a callback as soon as the component is loaded inside the bootstrap implementation?


I'm using data-sap-ui-onInit="module:my/custom/bootstrap" who's implementation ends with sap.ui.require(['sap/ui/core/ComponentSupport'].

Is there a way to get a callback as soon as the component is loaded inside the bootstrap implementation? I would like get a reference to the component object once it's initialised.


Solution

  • Without touching the Component.js content, if you can control both the initial HTML document (here: index.html) and the JS file assigned to data-sap-ui-oninit (here: myBootstrap.js) you can attach a handler to the ComponentContainer's events such as componentCreated or componentFailed like this:

    In index.html:

    <head ...>
      <!-- ... -->
      <script id="sap-ui-bootstrap"
        src="<...>resources/sap-ui-core.js"
        data-sap-ui-async="true"
        data-sap-ui-resourceRoots='{ "my.demo": "./" }'
        data-sap-ui-oninit="module:my/demo/myBootstrap"
        data-sap-ui-...="..."
      ></script>
    </head>
    <body id="content" class="sapUiBody">
      <!-- Only in UI5 1.x as registering a global event handler in HTML 
      like below is deprecated since UI5 1.120 and removed in UI5 2.x -->
      <div data-sap-ui-component
        data-id="myRootComponentContainer"
        data-name="my.demo"
        data-component-created="onMyComponentCreated"
        data-height="100%"
        data-settings='{ "id": "myRootComponent" }'
        data-...="..."
      ></div>
    </body>

    In myBootstrap.js:

    // ...
    globalThis.onMyComponentCreated = function(event) {
      const myCreatedComponent = event.getParameter("component");
      // ...
    };
    
    // === With UI5 1.x ===
    sap.ui.require(["sap/ui/core/ComponentSupport"]); // will register onMyComponentCreated only in UI5 1.x
    // ====================
    
    // === With UI5 2.x ===
    sap.ui.require([
      "sap/ui/core/ComponentContainer", // has to be created manually for this case only in UI5 2.x
    ], ComponentContainer => new ComponentContainer({
      id: "myRootComponentContainer",
      name: "my.demo",
      componentCreated: globalThis.onMyComponentCreated, // or an anonymous function
      height: "100%",
      settings: { id: "myRootComponent" },
      // Settings that sap/ui/core/ComponentSupport applies by default:
      lifecycle: "Container", // enum sap.ui.core.ComponentLifecycle
      autoPrefixId: true,
      manifest: true,
    }).placeAt("content"));
    // =======================
    

    Here, the handler name "onMyComponentCreated" is just a sample name. Make sure to create a name that would not cause a name collision in the global scope, or assign an anonymous function when creating a ComponentContainer manually.


    Regarding the data-component-created syntax:

    As HTML is case-insensitive, in order to define a property with upper-case characters, you have to "escape" them with a dash character. (From the API reference: sap/ui/core/ComponentSupport)

    For more information, review the documentation topic "Declarative API for Initial Components".