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
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
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.
route
OptionenExt.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.
routePath
nach route.path
Ext.define({
// ...
routePath: "demo"
//...
});
Die Information in route.path
ist mit dem Attribut routePath
synchronisiert.
Der |
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 |
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:
{
"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
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"
}]
});
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;
}
});