Search code examples
sapui5

How to retrieve view's ID with application prefix?


To retrieve prefixed ID of a control we can use view's method CreateID. However, there's no such a method in class sap.ui.core.Core. So how do I know viewID in the line

sap.ui.getCore().byId(viewID)


Solution

  • The Core is common to all the applications you are loading into your HTML document. An specific view of an specific application can have a different ID depending on how many different views you already loaded. The CreateID method makes sense to create an ID prefixed by the relevant View ID, but the view IDs are not prefixed but just autogenerated.

    So, to get the ID of the current view, just do this.getView() in its controller and get the ID from the returned object.

    If you want to know the ID of a different view to the one you are visualizing/loading, then you need to navigate through all the views in your DOM and design your own way to identify it.

    However I don't recommend you to modify a View from a controller of another view. Each View should be modified by the logic in its controller only, and no by other controllers, to maintain the principles of the MVC architecture

    EDIT:

    How to access your component:

    1. If you bind the context of your app execution with the Push.js script, then use this.getOwnerComponent().
    2. If you don't, then you need to access your Component from the core with sap.ui.getCore().getComponent('componentID')

    Now the problem is how to know the componentID. Well, I see two options here, give an ID to your component, or map the autogenerated component IDs in a Core variable.

    How to retrieve a specific Component:

    Option 1: Define a Component ID

    Whenever you initialize it, usually in the index.html file, you can do it like this:

         <script>
            sap.ui.getCore().attachInit(function() {
                sap.ui.component({
                    id: "myComponentID",
                    async: true,
                    name: "myNamespace", // The namespace you defined in the bootstrap tag and points to the folder where the Component.js file is stored
                    manifestFirst: true
                }).then(function(oNewComponent){
                    new sap.m.Shell({
                        app: new sap.ui.core.ComponentContainer({
                            component: oNewComponent,
                            height : "100%"
                        })
                    }).placeAt("content");
                })
            });
        </script>
    

    With this option you can retrieve your Component as sap.ui.getCore().getComponent('myComponentID') and of course whatever model registered in it with sap.ui.getCore().getComponent('myComponentID').getModel('modelName')

    Option 2: Map the autogenerated components IDs with your identifiers in a Core variable

    I don't like to change the Components ID, and there are some times when you have no chance to do it. So in the past I did it like in the following snippet (probably not the best/elegant solution out there, but it works good)

    Component.js

        /**
         * The component is initialized by UI5 automatically during the startup of the app and calls the init method once.
         * @public
         * @override
         */
        init: function() {
            //Map Component ID in a Core variable
            if(!sap.ui.getCore()._data_oLoadedComponents){
                sap.ui.getCore()._data_oLoadedComponents = {};
            }
            sap.ui.getCore()._data_oLoadedComponents.myCustomComponentId = this.getId(); // myCustomComponentId is the ID you want to use for this specific app
            // END: Map Component ID in a Core Variable
    
            // call the base component's init function
            UIComponent.prototype.init.apply(this, arguments);
    
            // set the device model
            this.setModel(models.createDeviceModel(), "device");
        }
    

    So now you can access any of your components getting the autogenerated ID from your mapping variable like this:

    sap.ui.getCore().getComponent(sap.ui.getCore()._data_oLoadedComponents.myCustomComponentId)
    

    and also access the model like this:

    sap.ui.getCore().getComponent(sap.ui.getCore()._data_oLoadedComponents.myCustomComponentId).getModel('modelName')