Why to wrap a `Dialog` with `FragmentDefinition`?

Viewed 348

An UI5 dialog can be defined directly as a Dialog:

<Dialog
    xmlns = "sap.m"
    id = "helloDialog"
    title = "Hello {/recipient/name}">
    <beginButton>
        <Button
            text = "{i18n>dialogCloseButtonText}"
            press = ".onCloseDialog" />
    </beginButton>
</Dialog>

Or can be wrapped by a FragmentDefinition:

<core:FragmentDefinition
    xmlns:core = "sap.ui.core"
    xmlns = "sap.m">

    <Dialog
        id = "helloDialog"
        title = "Hello {/recipient/name}">
        <beginButton>
            <Button
                text = "{i18n>dialogCloseButtonText}"
                press = ".onCloseDialog" />
        </beginButton>
    </Dialog>

</core:FragmentDefinition>

As far as I understand, a FragmentDefinition provides a higher degree of reuse since it doesn't depend on any view's controller but can be initialized with a custom controller using sap.ui.core.Fragment.load():

this._oDialog = await Fragment.load({
    controller: fragmentController,
    id: oView.getId(),
    name: "webapp.view.MyDialog"
});

However, according to the documentation, starting UI5 1.93, the loadFragment() function is available on every controller instance extending sap.ui.core.mvc.Controller and this API has several advantages over the generic sap.ui.core.Fragment.load() function.

If I use a loadFragment(), should I still wrap a Dialog with FragmentDefinition? I've tried both implementations, both of them work and I see a dialog on a view, so what are the benefits of using FragmentDefinition if I still can directly call a Dialog with loadFragment()?

1 Answers

The <core:FragmentDefinition> is a runtime artifact that is not part of the DOM but serves only the purpose of wrapping multiple XML root nodes in *.fragment.xml documents. I.e.:

Fragment with multiple root nodes

From the topic "Fragments with Multiple Root Nodes"

<core:FragmentDefinition xmlns="sap.m" xmlns:core="sap.ui.core"> <!--mandatory-->
  <Label text="..." />
  <Input />
  <Button text="..." />
</core:FragmentDefinition>

As XML documents need to have exactly one root node, to achieve XML fragments with multiple root nodes, an additional <FragmentDefinition> tag needs to be added as root element.

Fragment with a single root node

From the sample sap.m.ActionSheet

<!-- No need to wrap this single root node with <FragmentDefinition> -->
<ActionSheet id="actionSheet"
  xmlns="sap.m"
  xmlns:core="sap.ui.core"
  core:require="{ MessageToast: 'sap/m/MessageToast' }"
  title="Choose Your Action"
  showCancelButton="true"
  placement="Bottom">
  <Button
    text="Accept"
    icon="sap-icon://accept"
    press="MessageToast.show('Selected action is ' + ${$source>/text})" />
  <!-- ... -->
  <Button
    text="Other"
    press="MessageToast.show('Selected action is ' + ${$source>/text})"
  />
</ActionSheet>

As such, it is simply unnecessary for <Dialog> fragments too to use <core:FragmentDefinition>.


Note

  • The above applies only to XML fragments. JS fragments, for example, do not need FragmentDefinition. FragmentDefinition is not even a module you can require.
  • Whether the fragment was created via this.loadFragment, Fragment.load(), ...etc doesn't matter. <FragmentDefinition> plays a role only for the definition of fragments.
Related