Routing / Deep Links

Das BPC unterstützt die Verwendung von Deep Links. Dafür wird der sogenannte Hash (MDN Docs Location) der URL verwendet. Dort legt das BPC durch & getrennte Routen ab. Jede Route wird durch / in weitere Bestandteile aufgeteilt.

https://COMPANY.COM/bpc#/one/part&second/part

Navigations Route

Der Teil der Route der mit /_nav beginnt, ist die Navigations-Route. Dies ein optionaler Bestandteil, der auf ein Element der Navigation verweist. Da Module im BPC gleichzeitig an verschiedenen Stellen innerhalb der Navigation platziert werden können, zeigt dieser Teil auf die aktuelle Position in den Navigationseinstellungen. Dadurch kann im Falle eine Neuladens der Seite der richtige Zustand der Navigationselemente wiederhergestellt werden.

Wird das BPC nur mit Navigations Route und ohne Modul Route geladen, so wird das Modul aktiviert, dann hinter dem adressierten Teil der Navigation konfiguriert ist.

Syntax

Die Navigation weist eine Baumstruktur auf. Für die Adressierung eines Elements in diesem Baum, werden die viewItemId der jeweiligen Knoten aneinander gereiht.

Die Route /1/12/123 adressiert das Element mit der viewItemId 123

Beispiel abstrakte Navigationseinstellung
Illustration 1. Beispiel abstrakte Navigationseinstellung
Die Navigations Route sollte vom Modul-Entwickler nicht direkt verwendet werden. Für die Adressierung und Parametrisierung der BPC Module ist ausschließlich die Modul Route zu verwenden.

Modul Route

Ein Teil beginnt mit /module und adressiert ein Modul im BPC. Diese URL kann zusätzliche Parameter für das Zielmodul enthalten. Die Auswertung der Parameter obliegt dem Modul selbst.

Syntax

/module/MODUL-ID/INSTANCE-ID/RESERVED/ENCODED-MODULE-OPTIONS/ADDITIONAL-ROUTE-ELEMENT-1/ADDITIONAL-ROUTE-ELEMENT-n

MODULE-ID

Die ID des Moduls. Beispielsweise monitor

INSTANCE-ID

Die ID der jeweiligen Modul-Instanz. Wenn das Modul zusätzlich zu Instanzen eine allgemeine Modul-GUI anbietet, dann wird hier erneut die Modul-ID angegeben.

RESERVED

Die Position kam früher in einigen Modulen zum Einsatz und wird aktuell nicht mehr berücksichtigt.

ENCODED-MODULE-OPTIONS

An dieser Position kann ein QueryString (key=value&foo=bar) oder ein JSON ({"key":"value","foo":"bar"}) angegeben werden. Diese werden direkt an das Modul übergeben und können dort ausgewertet werden. Welche Optionen unterstützt werden, sollten in der jeweiligen Modul-Dokumentation angegeben werden.

ADDITIONAL-ROUTE-ELEMENT

Am Ende kann eine beliebige Folge von Elementen angehangen werden. Diese können durch das jeweilige Modul programmatisch (Programmatisches Routing) behandelt werden oder für das Deklaratorisches Routing genutzt werden (siehe Routing innerhalb von Modulen).

Routing innerhalb von Modulen

Deklaratorisches Routing

Das deklaratorische Routing orientiert sich stark an der Anordnung der Oberflächen Elemente (Ext.Components). Allgemein lässt sich sagen, dass alle Elemente in einer Baumstruktur angeordnet sind. Über das Routing lässt sich steuern, welche Linie von Wurzel zum Ast aktiv sein soll.

Der Route-Controller ermittelt automatisch anhand der sichtbaren Elemente die aktive Route und setzt den Pfad in der URL. Soll ein Element vom Routing erfasst werden, so muss dieses mindestens mit einer Pfad-Information versehen werden. Da die Anordnung der Elemente in der Regel Top-Down definiert wird, sollte der Pfad auch immer vom "Eltern-Element" gesetzt werden. Sollte ein Element in sich ein Routing benötigen kann, kann diese einen ergänzenden Pfad definieren.

Es ist möglich, dass in der Baumstruktur parallel verlaufende Pfade sichtbar sind. In diesem Fall wird dir Route in der URL mit eckigen Klammern versehen. Geklammerte Elemente sind gleichwertig und werden parallel aufgelöst.

Wird das BPC mit einer Route geladen, dann versucht der Route-Controller die Elemente entsprechend der Route nach und nach zu lokalisieren und zu aktivieren. Beim Lokalisieren der Ziel-Elemente wird potentielles asynchrones Erzeugen von Elementen berücksichtigt. Das Anwenden der Route kann von Module ganz oder auch nur teilweise übernommen werden. Siehe dafür applyRoute und applySubRoute.

Das BPC erzeugt für die MainView eines jeden Moduls eine Route (siehe Modul Route).

Die Konfiguration wird an den Elementen (muss von Ext.Component ableiten) über ein route Objekt konfiguriert.

Alle route Optionen
Ext.define({
// ...
route: {
    path: "demo",
    subPath: ":getSubPath",
    applySubRoute: "",
    applyRoute: "",
    name: "",
    subRouteOrder : ["bpcInstanceManagerInstanceGrid"]
}
//...
});

path

(String). Name der im Route Pfad für dieses Element gesetzt werden soll.

Beginnt der Pfad mit : dann wird angenommen, dass es sich um die Referenzierung eines Attributes oder einer Funktion an dem Element handelt. Dies wird versucht aufzulösen und an der Stelle gesetzt.

Beispiel: :getId führt dazu, dass an dem Element die Funktion getId() aufgerufen wird und das Ergebnis an die Stelle des Pfades gesetzt wird.

Alternativ kann der Pfad auch über das Attribute routePath direkt am Element gesetzt werden.

Abkürzung von routePath nach route.path
Ext.define({
// ...
routePath: "demo"
//...
});

Die Information in route.path ist mit dem Attribut routePath synchronisiert.

Der route.path sollte in der Regel über das Eltern-Element beim Definieren/Erzeugen des Kind-Elementes gesetzt werden und nicht in der Klassen-Definition des Kindes.

subPath

(String; Optional). Beschreibt ein Pfad für das Routing innerhalb des aktuellen Elementes. So kann zum Beispiel ein Grid den Pfad auf die Selektion seiner Zeilen übertragen.

Beginnt der Wert mit : wird dies wie bereits unter path beschrieben ausgewertet.

Ohne Definition von path (kann über Eltern-Elemente erfolgen) wird subPath ignoriert.

applyRoute

(String|Function; Optional). Ist eine Funktion oder Referenz auf eine Funktion (kann auch im ViewController liegen), der das Aktivieren der Zielkomponente übertragen wird. Die Funktion wird in dem Kontext ausgeführt, in dem diese definierte ist (z.Bsp. ViewController). Der Funktion wird dabei die noch aufzulösende Route als Array übergeben. In der Regel wird dabei nur das Erste Element im Array ausgewertet, aber die Funktion kann ab hier auch den restlichen Routing Prozess übernehmen. Die Funktion muss einen Promise zurückgeben, der aufgelöst wird, sobald das Routing beendet ist. Dabei hat der Promise ein Objekt der folgenden Form zurückzugeben:

applyRoute Promise Ergebnis
{
  "remainingRouteArray": "{string[]}",
  "currentRoot": "{Ext.Component}",
  "gotoSubRoute": "{boolean}"
}
remainingRouteArray

(Array; Optional). Ein Array das die noch zu verarbeitende Route enthält. Diese wird vom Route-Controller weiter abgearbeitet. Wird hier kein Array oder ein leeres Array zurückgegeben, dann Ended der Routing-Prozess.

currentRoot

(Ext.Component; Optional). Element von dem ausgehend die restliche Route (remainingRouteArray) aufgelöst werden soll.

gotoSubRoute

(Boolean; Optional). Wenn dieser Wert true ist, wird versucht im folgenden Routing den subPath aufzulösen.

applySubRoute

(String|Function; Optional). Diese Funktion arbeitet analog zu applyRoute, bezieht sich jedoch auf subPath.

Beispiel

Routing Beispiel - TabPanel
Ext.define("BPCMODULE.view.Main", {
   extend : "Ext.tab.Panel",

   title : "Main View - I'm a TabPanel",

   items : [{
      // this tab will produce the route .../child1
      title     : "1",
      html      : "Child 1",
      routePath : "child1"
   },
   {
      // this tab will produce the route .../child2/[/child21,/child2n]
      title     : "2",
      xtype     : "panel",
      routePath : "child2",
      layout    : "hbox",
      items     : [{
         title     : "2.1",
         html      : "Child 2.1",
         routePath : "child21"
      },
      {
         title     : "2n",
         html      : "Child 2n",
         routePath : "child2n"
      }]
   }, {
      // this tab will produce the route .../child3/child31
      title     : "3",
      html      : "Child 3",
      routePath : "child3",
      items     : [
         {
            title     : "31",
            html      : "Child 31",
            routePath : "child31"
         }
      ]
   },
   {
      // this tab will produce the route .../childn
      title     : "n",
      html      : "Child n",
      routePath : "childn"
   }]

});
Routing Beispiel - Card Layout
Ext.define("BPCMODULE.view.Main", {
   extend : "Ext.container.Container",
   controller : "mainController",

   title : "Main View - I'm a Card Layout",

   layout : {
      type : "card",
   },

   items : [
      {
         xtype  : "container",
         routePath : "start", // this card will produce the route .../start
         items     : [
            {
               xtype       : "button",
               itemId      : "newPageBtn",
               routeTarget : "page1"   // routeTarget is the same as xtype of view we want to show
            }
         ]
      },
      {
         xtype     : "page1",
         routePath : "newPage"
      }   
   ]

});


Ext.define("BPCMODULE.view.NewPage", {
   extend : "Ext.container.Container",
   alias  : "widget.page1",

   controller : "mainController",

   title : "Page1 - Card Layout",

   layout : {
      type : "card"
   },
   
   items : [
      {
         xtype  : "container",
         routePath : "overview", // this card will produce the route .../overview/newPage
         items     : [
            {

            }
         ]
      }
   ]
});

Ext.define("BPCMODULE.view.MainController", {
   extend : "Ext.app.ViewController",
   alias  : "controller.mainController",

   control : {
      "button[routeTarget]" : {
         click : "showTargetView"
      }
   },

   showTargetView : function (button, event) {
      event.stopPropagation();
      event.stopEvent();
      const routeTarget = button.routeTarget;

      if (routeTarget) {
         const layout = this.getView().getLayout();
         const targetView = Ext.ComponentQuery.query(routeTarget)[0];
         layout.setActiveItem(targetView);
      }
      return false;
   }
});

Programmatisches Routing

TODO


Keywords: