sapui5sap-fiori

UI5 Fragment (not view) extension points from standard app ignored by framework


In the SAPUI5 documentation, views and controller extensions are mentioned, in many different ways of extending it. However, Fragment extension is not mentioned, and I came across a standard Fiori Manage Promotional Offers App which uses many Fragments and each one has many tags. And these EPs are being ignored by the framework. The app extension's page is outdated as if you look through the SAP Notes they introduced many more EPs than what they have in this documentation.

After debugging the standard ExtensionPoint (EP) class, I noticed it doesn't matter what you configure in the Component manifest customising, because these EPs are being ignored by the framework.

My manifest.json code trying to invoke the Fragment EP (I'm sure of the path and ext name as I debugged the std:

My manifest.json code trying to invoke the Fragment EP (I'm sure of the path and ext name as I debugged the std)

A working example of a View Extension (instead of a Fragment) in Component-dbg.js (observe the _sOwnerId prop and validation call to getOwnerIdFor() ): A working example of a View Extension (instead of a Fragment)

And the non-working extension from the Fragment: And the non-working extension from the Fragment

Question now is, does SAP need to fix their code to ensure the Fragment has a parent/owner so it will pass the above validation line and therefore trigger my extension? I have manually bypassed it in debug and got the extension working without a problem.

Or, are Fragment extensions not supported at all and not supposed to be used? But then why SAP would add so many EPs to Fragments? Or am I missing something and not using the Fragment extension properly? As mentioned I could not find any documentation on this.


Solution

  • TL;DR: if you can control when and how the fragment gets created, refer to the below linked documentation. Otherwise, create a customer incident to inform the application developers to provide a fix in their code accordingly.


    The most important documentation regarding this issue can be found at: The Owner Component

    Whether the framework incorporates the extension implementation or not depends on how the app creates the fragment or view that contains the extension point.

    As you highlighted in your screenshots, the internal ManagedObject property _sOwnerId refers to the ID of the "owner" Component instance that was known during the instantiation of the ManagedObject. The owner component ID (_sOwnerId) is, in most cases, automatically assigned by the framework.

    But if the application creates a ManagedObject outside of the "framework-managed features"1, from the framework's perspective, it's a simple class instantiation without any context of Components. Typically, this is the case when the ManagedObject creation occurs in an asynchronous callback function or when the user presses a UI element that initiates creating the ManagedObject on-demand. In such cases, the application has to provide the ID of the owner component of which the app descriptor (manifest.appdescr) has the extension information. This can be done, for example:

    • by using the newer API this.loadFragment (available since UI5 1.93), which automatically assigns the owner ID, when creating a fragment in the controller code.2
    • by running the ManagedObject creation within this.getOwnerComponent().runAsOwner(function () {/* Fragment.load, XMLView.create, etc.*/}.bind(this));.3

    Why is the issue happening in the app?

    Most likely, the application you mentioned is calling the API sap.ui.*fragment, Fragment.load, sap.ui.*view, or *View.create outside of the "framework-managed features"1 and directly without this.getOwnerComponent().runAsOwner which is why the created fragment doesn't have any _sOwnerId assigned.
    Keep in mind that declaratively assigned <core:Fragment fragmentName="..." type="..."/> in the view definition cannot have any owner ID assigned either if the view itself is also created without any owner ID.

    But why is it happening now?

    In the past (I believe until around UI5 1.94), it used to "work" accidentally without the above documented solution due to a bug. UI5 fixed the bug. Albeit the owner component is not a well-known topic, applications should've used the runAsOwner API or migrated to the newer controller API loadFragment early instead of relying on the observed behavior that accidentally worked.

    Another possible reason is that the application code has changed e.g. from creating the ManagedObject synchronously within the controller's onInit handler, where the owner ID is still known to the framework, to creating it within an asynchronous callback function.



    1 See the section "What is Handled by the Framework?" in the above linked documentation.
    2 API: sap.ui.core.mvc.Controller#loadFragment
    3 API: sap.ui.core.Component#runAsOwner