sapui5sap-fiori

Why are certain app extensions 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 fragments or views are created, refer to the below linked documentation. Otherwise, create a customer incident to inform the base application developers to provide a fix in their source code.


    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 ManagedObject to which the extension is supposed to be applied (Here: fragment). As highlighted in the screenshot, the internal ManagedObject property _sOwnerId refers to the ID of the owner Component instance that was known during the instantiation of the target ManagedObject. The owner component ID (_sOwnerId) is, in most cases, automatically assigned by the framework.1

    Why is the issue happening in the app?

    The application is calling the API sap.ui.*fragment, Fragment.load, sap.ui.*view, or *View.create outside of the "framework-managed features"1 and without any runAsOwner. Nesting <core:Fragment .../> / <mvc:View .../> declaratively doesn't help either if the parent itself won't be created with a component ID.

    If the application creates the ManagedObject outside of the "framework-managed features", from the framework's perspective, it's a plain class instantiation without any relation to existing Component. 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 ensure that the ID of the owner component is assigned2 when calling Fragment.load, View.create, etc.

    The owner component here is the component that contains the target extension information either in the app descriptor at runtime (manifest.appdescr) or in the Component controller's legacy code at /metadata/customizing (if there is no manifest: "json").

    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 Component IDs can be automatically assigned either by calling myController.loadFragment or during the function execution within myComponent.runAsOwner.

    View or Controller Extension is Not Loaded or KBA 3280815 might also help in identifying other possible issue scenarios.