docs

The Owner Component

If you wish to extend your view or controller, you must define the extension in the manifest.json of their owner component.


What is the Owner Component?

Technically, the owner component is the sap.ui.core.(UI)Component instance which created (and thus “owns”) any sap.ui.base.ManagedObject instance. This of course includes all subclasses of ManagedObject, e.g. any OpenUI5 control, as well as views, fragments, and even other (UI)Components.

One of the most common use cases of the owner component is the extensibility of (UI)Components. The framework uses the owner component to identify extension points, view modifications, and controller extensions from the owner component’s manifest.json.


What is Handled by the Framework?

For the most part, the framework takes care of setting and propagating the owner component throughout all framework-managed control and Component creation mechanisms. This includes the following:

Note:

The owner component for ManagedObjects is assigned by the framework at the time when they are created. It is not updated afterwards, for example if a control is moved from one Component’s control tree to another.

We advise you not to move controls over Component boundaries.


What Needs to be Handled by the Application?

Any ManagedObject that is created outside the above-listed framework-managed features is not automatically assigned an owner component. This is a very common occurrence, since a lot of ManagedObjects (e.g. fragments) will be created after the startup of a Component at an unknown point in time. For example, an sap.m.Dialog with fragment content might only be created upon user interaction.

Since the owner component is the carrier of extension information through its manifest.json, your views, fragments, and controllers rely on the connection to an owner component to look up any extension configuration and apply it accordingly. The framework cannot apply extensions for views, fragments, and controllers if no owner component is known. These scenarios must be handled by the application.


Best Practices for Creating Controls

Whenever possible, use one of the above-listed framework-managed control creation mechanisms.

If this is not possible, you can assign the correct owner component manually by retrieving the Component instance and wrapping any code that creates a ManagedObject inside a runAsOwner() call on the Component instance:

// In this sample, the 'this' context is a controller instance
// The controller class provides a shorthand getter for its owner component
var oComponent = this.getOwnerComponent();
// oComponent is now the owner component instance which owns the controller
oComponent.runAsOwner(() => {
    // create additional ManagedObjects here, e.g. via
    //   * a View and Fragment factory
    //   * or simply via a control's constructor
    XMLView.create(/*...*/).then(() => {
        // Due to the asynchronous nature of the XMLView factory
        // the owner-component scope is lost again inside the 'then' handler!
        // Make sure to call runAsOwner again if more controls are created here.
    });
    Fragment.load(/*...*/).then(/*...*/);
    new Button(/*...*/);
});

A common use case for asynchronous operations is the UIComponent#createContent method. Components implementing the sap.ui.core.IAsyncContentCreation interface can use an async implementation here.

Using async/await might give you the impression that your code is executed synchronously and a manual setting of the owner component is not needed anymore. This is not the case, however.

The comments in the following code sample outline some common pitfalls and misconceptions:

MyComponent.prototype.createContent = async function() {
    // the first async break is still in the owner scope of "this"
    // as up to this point all statements are running in the same execution stack and the framework tracks the owner component for you
    const firstView = await XMLView.create(/*...*/);
    myView.byId("...").setValue("abc");

    // This is a second async break in the implementation, and the owner component scope is lost to the framework
    // From here on, you need to wrap every async call into a "runAsOwner" call (refer also to the sample above)
    const secondView = await this.runAsOwner(() => {
        return XMLView.create(/*...*/);
    });

    // do some more work with your views/fragments

    // and return the controls you want to aggregate in the UIComponent's "rootControl" aggregation
    // Alternatively, you can return another Promise resolving with controls
    return firstView;
};

Note:

Since the owner-component scoping is only active during the execution of the runAsOwner function, the then(...) handlers of the factory promises are not scoped anymore! You would need to call runAsOwner again in such a case.

If ManagedObjects need to be created outside a controller instance, the static sap.ui.core.Component.getOwnerComponentFor function can be used:

// 'oPage' is a examplary sap.m.Page control, the static API however accepts all ManagedObjects
// Note: though all ManagedObjects can be passed to this function, the owner component can only
//       be returned for ManagedObjects that have an owner component assigned already
var oComponent = Component.getOwnerComponentFor(oPage);
oComponent.runAsOwner(() => {
    // same as in the above sample
});

Related Information

sap.ui.core.Component.getOwnerComponentFor

sap.ui.core.Component.prototype.runAsOwner

sap.ui.core.Component.getOwnerIdFor