UI5: layout multicolonna

UI5 prevede una metodologia standard per renderizzare una schermata con due colonne; il caso d'uso tipico è nelle viste di dettaglio: la colonna di sinistra (stretta) mostra una lista di oggetti, e la colonna di destra mostra i dettagli dell'oggetto selezionato. Questa modalità è perfettamente integrata nel sistema di routing e può essere implementata con pochi accorgimenti.

Voglio provare a costruire un piccolo esempio di vista master-detail. Per non ripartire da zero, userò come punto di partenza l'applicazione di prova realizzata nel precedente post, e mostrerò solo le modifiche per portarla da un layout singolo (una schermata per la lista, un'altra per i dettagli) a un layout multicolonna.

Per prima cosa si può modificare la view master dell'applicazione, quella che contiene il tag "app". Questo verrà sostituito dal tag "SplitApp":

 <!-- MainView.view.xml -->
 
 <mvc:View controllerName="it.tutorial.provaUI5.controller.MainView"
  displayBlock="true"
  xmlns="sap.m"
  xmlns:mvc="sap.ui.core.mvc">

  <SplitApp id="idAppControl" />
  
</mvc:View>

A questo punto è sufficiente modificare il sistema di routing nel manifest.json per gestire questa nuova modalità di visualizzazione.

Si noti come adesso gli oggetti "routes" e "targets" assumono significati ben distinti, mentre nel caso semplice visto in precedenza apparivano abbastanza sovrapposti (ad ogni route corrispondeva uno specifico target).

Le routes, come visto in precedenza, sono delle associazioni tra un pattern e un array di target. Abbiamo due route:

  • una route di default, che mostrerà la lista nella parte sinistra e lascerà vuota la parte destra della schermata.
  • una route di dettaglio (quella con la variabile "id" nel pattern), che manterrà la lista a sinistra ma mostrerà il dettaglio nella parte destra (si noti che ora l'array "target" contiene due riferimenti).
...      
      "routes": [
        {
          "name": "FirstRoute",
          "pattern": "",
          "target": [
            "ListView"     <-- Lista
          ]
        },
        {
          "name": "ProductDetail",
          "pattern": "detail/{id}",
          "target": [
            "ListView",    <-- Lista
            "DetailView"   <-- Dettaglio
          ]
        }		
      ],
...

Per quanto riguarda la parte "targets", l'unica modifica richiesta è specificare per ciascun target il nome dell'aggregazione in cui inserire la vista cui il target si riferisce. Nella versione precedente, questo era specificato in una variabile comune "controlAggregation" nella sezione "routing"->"config", e conteneva il valore "pages", che è il nome dell'aggregazione contenuta nell'oggetto "App".

...   
    "routing": {
      "config": {
        "controlAggregation": "pages",
        ...
...

Nella nuova versione dobbiamo differenziare tra l'aggregazione che conterrà le viste di sinistra (masterPages) e quella che contiene le viste di destra (detailPages) per il tag "SplitApp". Dobbiamo quindi rimuovere la voce "controlAggregation" di cui sopra e andare a piazzare la stessa in ciascun target, prestando attenzione ad utilizzare il valore corretto.

...
      "targets": {
        "ListView": {
          "viewType": "XML",
          "viewId": "ListView",
          "viewName": "ListView",
          "controlAggregation": "masterPages"
        },
        "DetailView": {
            "viewType": "XML",
            "viewId": "DetailView",
            "viewName": "DetailView",
            "controlAggregation": "detailPages"
        }
      }
...

Se abbiamo fatto tutto per il meglio il risultato dovrebbe essere una cosa del genere:

Voilà!