Routing / Deep Links

The BPC supports the use of deep links. To do this, it uses the URL’s “hash” (MDN Docs Location). There, the BPC stores routes separated by “ &.” Each route is divided into further components by /.

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

Navigation Route

The part of the route that begins with /_nav is the navigation route. This is an optional component that refers to an element in the navigation. Since modules in the BPC can be placed in multiple locations within the navigation at the same time, this part points to the current position in the Navigation Settings. This ensures that the correct state of the navigation elements is restored if the page is reloaded.

If the BPC is loaded only with [_navigations_route] and without [_modul_route], the module is activated and then configured after the addressed part of the navigation.

Syntax

The navigation has a tree structure. To address an element in this tree, the viewItemId of the respective nodes are concatenated.

The route /1/12/123 addresses the element with the viewItemId 123

Example of abstract navigation configuration
Illustration 1. Example of abstract navigation configuration
The [_navigations_route] should not be used directly by the module developer. Only [_modul_route] should be used for addressing and configuring BPC modules.

Module Route

A segment begins with /module and addresses a module in the BPC. This URL may contain additional parameters for the target module. The module itself is responsible for evaluating these parameters.

Syntax

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

MODULE-ID

The ID of the module. For example, monitor

INSTANCE-ID

The ID of the respective module instance. If the module offers a general module GUI in addition to instances, the module ID is specified here again.

RESERVED

This position was previously used in some modules but is no longer taken into account.

ENCODED-MODULE-OPTIONS

A query string (key=value&foo=bar) or JSON ({"key":"value","foo":"bar"}) can be specified at this position. These are passed directly to the module and can be evaluated there. The supported options should be specified in the respective module documentation.

ADDITIONAL-ROUTE-ELEMENT

Any sequence of elements can be appended at the end. These can be handled programmatically by the respective module ([_programmatisches_routing]) or used for the [_deklaratorisches_routing] (see [_routing_innerhalb_von_modulen]).

Routing Within Modules

Declarative Routing

Declarative routing is strongly based on the arrangement of interface elements (Ext.Components). Generally speaking, all elements are arranged in a tree structure. Routing can be used to control which path from the root to a branch should be active.

The route controller automatically determines the active route based on the visible elements and sets the path in the URL. If an element is to be included in routing, it must be provided with at least one piece of path information. Since the order of elements is typically defined top-down, the path should always be set by the “parent element.” If an element requires its own routing, it can define an additional path.

It is possible for parallel paths to be visible in the tree structure. In this case, the route in the URL is enclosed in square brackets. Bracketed elements are equivalent and are resolved in parallel.

If the BPC is loaded with a route, the route controller attempts to locate and activate the elements one by one according to the route. When locating the target elements, potential asynchronous creation of elements is taken into account. The application of the route can be handled entirely or only partially by modules. See applyRoute and applySubRoute for more information.

The BPC generates a route for the MainView of each module (see [_modul_route]).

The configuration is set on the elements (which must extend from Ext.Component ) via an route object.

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

path

(String). Name to be set in the route path for this element.

If the path begins with :, it is assumed that this refers to an attribute or a function on the element. An attempt is made to resolve this and set it in place.

Example: :getId causes the function getId() to be called on the element, and the result is set in place of the path.

Alternatively, the path can also be set directly on the element using the routePath attribute.

Abbreviation for routePath to route.path
Ext.define({
// ...
routePath: "demo"
//...
});

The information in route.path is synchronized with the routePath attribute.

The route.path should generally be set via the parent element when defining/creating the child element, and not in the child’s class definition.

subPath

(String; Optional). Describes a path for routing within the current element. For example, a grid can pass the path to the selection of its rows.

If the value begins with :, it is evaluated as described at path.

Unless ` path ` is defined (which can be done via parent elements), ` subPath ` is ignored.

applyRoute

(String|Function; Optional). A function or reference to a function (which may also reside in the ViewController) to which the activation of the target component is delegated. The function is executed in the context in which it is defined (e.g., ViewController). The route still to be resolved is passed to the function as an array. Typically, only the first element in the array is evaluated, but the function can also take over the rest of the routing process from this point on. The function must return a Promise that resolves as soon as routing is complete. The Promise must return an object in the following format:

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

(Array; Optional). An array containing the routes still to be processed. This is further processed by the route controller. If no array or an empty array is returned here, the routing process ends.

currentRoot

(Ext.Component; Optional). Element from which the remaining route (remainingRouteArray) is to be resolved.

gotoSubRoute

(Boolean; Optional). If this value is true, an attempt is made to resolve the subPath in the subsequent routing.

applySubRoute

(String|Function; Optional). This function works similarly to applyRoute, but refers to subPath.

Routing Examples

  • TabPanel

  • Card Layout

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;
   }
});

Programmatic Routing

TODO


Keywords: