XML Fragment

Mit XML-Fragments die Übersichtlichkeit deiner Anwendung verbessern

Nach kurzer Sommerpause geht es weiter mit der Expedition durch die SAPUI5 Welt. Heute beschäftigen wir uns mit dem Einsatz von XML-Fragments in den eigenen Anwendungen.

Fangen wir an mit einer kurzen Definition:
Fragments sind ausgelagerte Code-Schnipsel, die in eigenen Dateien gekapselt werden. Sie beinhalten ausschließlich UI-Elemente, besitzen also keinen eigenen Controller. Die Auslagerung dient in der Regel einem der folgenden Zwecke:

  • Der Code-Schnipsel soll an unterschiedlichen Stellen der Anwendung zum Einsatz aber nicht mehrmals gecodet werden(Stichwort Codeverdopplung)
  • Die Auslagerung dient der Übersichtlichkeit eines Views
  • Das UI-Schnipsel ist nicht direkt in einem View verankert (z.B. ein Dialog)

XML-Fragments können beliebig komplex sein. Meiner Meinung nach macht es aber Sinn diese einfach zu halten und im Zweifel lieber ein weiteres Fragment anzulegen als ein einziges zu überladen. In meinen Anwendungen beinhaltet ein Fragment oftmals nur ein einziges Control.

Zusätzliche Info: Es gibt weitere Arten von Fragments (HTML, JS, etc.), auf die ich hier aber nicht eingehen werde. Der Vollständigkeit halber seien sie aber hier kurz erwähnt.

Wie sieht ein Fragment aus?

Ein Fragment hat ein umschließendes Tag „FragmentDefinition“. Anders als bei einem View wird kein Controller-Name mitgegeben, da das Fragment, wie oben schon erwähnt, keinen eigenen Controller besitzt.

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

Innerhalb dieses Tags können alle bekannten SAPUI5 Controls verwendet werden. Um zu zeigen, wie einfach ein Fragment gestaltet werden kann gucken wir uns folgendes an:

<core:FragmentDefinition xmlns="sap.m" xmlns:core="sap.ui.core">
  <Button text="Drück mich" press="onPressFragmentButton" />
</core:FragmentDefinition>

Es besteht aus einem einzigen Button. An der Stelle hätte wir jetzt weitere Controls einfügen oder komplexe Strukturen aufbauen können. Für unsere Zwecke ist der Button aber vollkommen ausreichend. Die Datei speichern wir mit dem Suffix .fragment.xml, also beispielsweise MyDrueckMichButton.fragment.xml.

An dieser Stelle eine kurze Bemerkung zum Speicherort:
Je mehr wir mit Fragments arbeiten, desto unübersichtlicher wird unsere Ordnerstruktur. Es empfiehlt sich, sich vorher Gedanken zu machen, wie Fragments verortet werden sollen. Das kann ein einfacher Ordner fragments sein oder, je nach Bedarf, auch mit größerem Detaillierungsgrad. Meiner Erfahrung nach werdet ihr dankbar darüber sein, wenn ihr diese Überlegung am Anfang macht und nicht erst, wenn ihr die Übersicht in eurer Ordnerstruktur verloren habt. Bei letzterem spreche ich aus eigener Erfahrung.

So, jetzt haben wir einen Teil unseres Codes gekapselt. Der erste Schritt ist getan. Als nächstes gucken wir uns an, wie wir unser Fragment in unsere Anwendung einbinden können. Dafür stehen uns mehrere Möglichkeiten zur Verfügung.

01 – Einbindung direkt im XML

Wir können unser Fragment direkt in einem XML-View integrieren. Dadurch wird es zu dem Zeitpunkt gerendert wie auch der View gerendert wird. Außerdem wird das Fragment in den “Lifecycle” unseres Views integriert. Dadurch kann es auf den Controller des Views zugreifen und auch alle verfügbaren Models des Views im Fragment zum Binding verwenden.
Die Syntax ist wie folgt:

…
<core:Fragment 
  fragmentName="myApp.fragments.MyDrueckMichButton" 
  type="XML" />
…

02 – Aufruf über einen Controller

Wir können unser Fragment auch zu jedem beliebigen Zeitpunkt im Controller instanziieren. Der klassische Anwendungsfall dafür ist die Öffnung und Anzeige eines Dialogs. Für dieses Beispiel sei folgendes Fragment gegeben:

<core:FragmentDefinition xmlns="sap.m" xmlns:core="sap.ui.core">
  <Dialog title ="Information">
    <content>
      <Label 
        text="Ich bin ein Dialog und wurde gerade geöffnet" />
    </content>
    <buttons>
      <Button 
        text="Abbrechen"
        press="onCloseDialog" />
    </buttons>
  </Dialog>
</core:FragmentDefinition>

Im Controller schreiben wir uns jetzt eine Methode, die diesen Dialog öffnet. In diesem Zuge achten wir auch gleich darauf, dass wir unseren Dialog wiederverwendbar machen. Wir möchten nämlich nicht bei jedem Öffnen des Dialogs einen neuen Dialog rendern sondern, sofern möglich, einen Dialog einmal erstellen und dann wiederverwenden.

…
onOpenDialog: function() {
  // Prüfung, ob unser Dialog schon erstellt wurde
  if (this._dialog != null) { 
    // Speicherung des Dialogs in einer globalen Variablen
    this._dialog = sap.ui.xmlfragment(
      "myApp.fragments.InfoDialog", 
      this
    );
    this.getView().addDependent(this._dialog);
  }
 
  this._dialog.open();
},

onCloseDialog: function() {
  this._dialog.close();
}
…

Auf unserem Dialog befindet sich ein Button mit einer Funktion “onCloseDialog”. Diese wird im Controller des Views implementiert. Damit der Dialog diese Funktion verwenden kann muss beim Erstellen des Dialogs darauf geachtet werden, dass der Controller als Parameter mitgegeben wird. (In unserem Beispiel der zweite Parameter “this”).
An dieser Stelle kann man viel Zeit und Nerven verlieren. Wenn also eine Funktion nicht aufgerufen wird obwohl sie es sollte empfehle ich das zuerst zu prüfen. Wieder spreche ich hier aus eigener Erfahrung.

03 – Einbindung über einen Extension Point

Die Einbindung über Extension Points ist die fortgeschrittenste Variante. Über Extension Points können Anwendungen, die auf der gleichen Anwendung basieren und nur wenig Unterscheidung hinsichtlich Erscheinung und Funktionalität haben, so erweitert werden, dass sie ein neues Gesicht und unterschiedliche Funktionalitäten bekommen.
In der Basis Anwendung wird ein Extension Point an der Stelle im View definiert, an der eine Erweiterung möglich sein soll.

…
<core:ExtensionPoint name="extension1" />
…

Dieser wird dann über ein Extension Project mit Inhalt gefüllt wird. Die Erweiterung im Extension Project wird standardmäßig in der manifest.json vorgenommen.

…
"sap.ui5": {
  "extends": {
    "extensions": {
      "sap.ui.viewExtensions": {
        "myApp.view.Main": {
          "extension1": {
            "className": "sap.ui.core.Fragment",
            "fragmentName": "myExtApp.view.MyDrueckMichButton",
            "type": "XML"
          }
        }
      }
    }
  }
}
…

Diese Methode ist, wie schon gesagt, eher etwas für fortgeschrittene Entwickler. Wenn man aber etwas mit dem Erweiterungsprinzip von SAP Fiori Anwendung vertraut ist, dann sollte man sich hier relativ schnell zurechtfinden.

Fazit

Die Nutzung von Fragments macht Sinn und ist ein absolutes Muss, je größer und komplexer die eigenen Anwendungen werden. Aber auch bei einfachen Anwendungen ist die Nutzung sehr zu empfehlen (Stichwort Dialog). Mit dem klassischen Erweiterungsprinzip in SAP Fiori Anwendungen kommt man dann schlussendlich sowieso nicht mehr umhin Fragments zu nutzen.
Ich hoffe, dass dieser Beitrag helfen kann, bestehende Hürden für die Nutzung von Fragments abzubauen. Sie bieten eine einfache Möglichkeit die Code-Qualität zu erhöhen und die eigenen Anwendung übersichtlicher und besser wartbar zu gestalten und sollten deshalb auch soft wie es Sinn macht wahrgenommen werden.

Bis dahin erstmal und kiek mol wedder in!

 

Du interessierst dich für Fiori und hast Lust coole Projekte mit uns zu machen? Wir suchen dich! Schau doch mal in unserer Stellenbeschreibung vorbei.

Über den Autor

Sebastian Kielhorn

Kommentar verfassen