Skip to Content

Implementation Details of Route in SAPUI5

This is my first blog for UI5, just want to share some details founding. Correct me if I’m wrong.

Go to github for better markdown experience: https://github.com/TinaC/Blog/blob/master/SAPUI5/Route.md

Here is a discussion about Router and Target: https://stackoverflow.com/questions/46336762/what-is-the-difference-between-sap-ui-core-routing-router-navto-and-sap-m-rout

Source code involves:
https://github.com/SAP/openui5/blob/master/src/sap.m/src/sap/m/routing/Router.js
https://github.com/SAP/openui5/blob/master/src/sap.ui.core/src/sap/ui/core/UIComponent.js https://github.com/SAP/openui5/blob/master/src/sap.ui.core/src/sap/ui/core/routing/Router.js

The reason I dig into the source code is I want to understand why `View` can change when I call `Router.navTo()`.

Take this offical demo as an example:
https://sapui5.hana.ondemand.com/#/sample/sap.ui.core.sample.RoutingFullscreen/preview

From the source code of `navTo`, it seems has nothing to do with View:
https://github.com/SAP/openui5/blob/master/src/sap.ui.core/src/sap/ui/core/routing/Router.js#L514

// third party hasher.setHash() is called in sap.ui.core.routing.HashChanger
HashChanger.prototype.setHash = function(sHash) {
  this.fireEvent("hashSet", { sHash : sHash });
  hasher.setHash(sHash);
};

 

So I think the event might be registered in `Component.init()`

# What `UIComponent.prototype.init` do for Route?

## manifest.json is defined in Demo

Component.js:
call `UIComponent.prototype.init`

 

init : function () {
  UIComponent.prototype.init.apply(this, arguments);
  this.getRouter().initialize();
}

 

## sap.ui.core.UIComponent.js

In function `UIConfig.prototype.init`, router constructor is called:
https://github.com/SAP/openui5/blob/master/src/sap.ui.core/src/sap/ui/core/UIComponent.js#L257

`var oRoutingManifestEntry = this._getManifestEntry(“/sap.ui5/routing”, true) || {}`
returns config in manifest.json. (metadata.routing.routes)

`vRoutes = oRoutingManifestEntry.routes;`
vRoutes is used for storing `routes` config

[function getConstructorFunctionFor ](https://github.com/SAP/openui5/blob/master/src/sap.ui.core/src/sap/ui/core/UIComponent.js#L307) using `jQuery.sap.getObject` to get constructor of `sap.m.routing.Router`

And then the constructor is called:
`this._oRouter = new fnRouterConstructor(vRoutes, oRoutingConfig, this, oRoutingManifestEntry.targets);`

The four arguments stands for:

* vRoutes: metadata.routing.routes
* oRoutingConfig: metadata.routing.config
* this: UIComponent itself,for view creation
* oRoutingManifestEntry.targets: metadata.routing.targets

The constructor call make the process jump to `sap.m.routing.Router` :

var MobileRouter = Router.extend("sap.m.routing.Router",{
  constructor : function() {
    this._oTargetHandler = new TargetHandler();

    Router.prototype.constructor.apply(this, arguments);
  }
}

As we know, sap.m.routing.Router(Mobile Router) extend `sap.ui.core.routing.Router`:
The four arguments corresponding to the previous four.

`this._oRouter = crossroads.create();`
a new independent Router instance is created by the third party routing library [crossroads](
https://millermedeiros.github.io/crossroads.js/#crossroads-create),

this._oViews = new Views({
  component : oOwner,
  async : this._oConfig._async
});

Views that are using in the routes are created, which can be using in `Router.getView()` and `Router._createTargets` etc.:

getViews : function () {
  return this._oViews;
},

//_createTargets is called in constructor if metadata.routing.targets exists
_createTargets : function (oConfig, oTargetsConfig) {
  return new Targets({
    views: this._oViews,
    config: oConfig,
    targets: oTargetsConfig
  });
},

 

if target config exist, creates targets(call `Targets` constructor) and stores them in `this._oTargets`, `this._oTargets` will be used in `Router.initialize()`

Call Stack:
[sap.m.rounting.Targets.constructor](https://github.com/SAP/openui5/blob/master/src/sap.m/src/sap/m/routing/Target.js#L39) => [sap.ui.core.routing.Targets.constructor](https://github.com/SAP/openui5/blob/master/src/sap.ui.core/src/sap/ui/core/routing/Targets.js#L293) => [sap.ui.core.routing.Targets._createTarget()](https://github.com/SAP/openui5/blob/master/src/sap.ui.core/src/sap/ui/core/routing/Targets.js#L523)

Finally, I think I found the view display register function:

// _createTarget()
oTarget.attachDisplay(function (oEvent) {
  var oParameters = oEvent.getParameters();

  //break point here
  this.fireDisplay({
     name : sName,
     view : oParameters.view,
     control : oParameters.control,
     config : oParameters.config,
     data: oParameters.data
  });
}, this);

Set a breakpoint in `this.fireDisplay`, and you can see the call stack.

The `hasher.setHash()` called in `navTo` fires `hashChanged` event and `_routeMatched` event, and then the `_display` event is fired. And then View is displayed.

1 Comment
You must be Logged on to comment or reply to a post.
  • Well – I admit I had a bit of trouble reading this one.  A quick suggestion would be to put the code in a code block and your observations outside of it.

    Congrats on the first UI5 blog,

    Michelle