Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Routing in SAPUI5: How to implement passing of URL? Model data not initialy loaded

My goal is to write a SAPUI5 Fiori app with routing support. One mail goal is to have passable URLs. For example in an E-Mail like "please approve this: link". The link is an URL matched by my rounting config, e.g.index.html#/applicants/8.

I use a typical sap.m.SplitApp kind of application. Clicking a list item in masterview changes the URL to index.html#/applicants/[id of entry in JSON]. I can click on the list, my defined routes are getting matched and the apps loads the (applicant) data as expected.

However, and here comes my question, this doeas not work when using an URL directly, say pasting [my url]/index.html#/applicants/8 into my browser. The app is launched but no detail data is loaded. I have to click on another list item again to get the data.

Actually, the controller is called when passing the URL, but it seems the model is not initiated and undefined. My JSON model is bound in the createContent function of my Component.js

// Update 2015-05-14 The problems seems to be around the getData() function. I have the model, it has the entries, but getData() returns undefined for the first time my app is loaded. I recently read getData() is deprecated. How should I improve my coding below?

// Component.js
ui5testing.Component.prototype.createContent = function(){
  // create root view
  var oView = sap.ui.view({
    id : "app",
    viewName : "ui5testing.view.Main",
    type : "JS",
    viewData : {
        component : this
    }
  var oModel = new sap.ui.model.json.JSONModel("model/mock_applicants.json");
  oView.setModel(oModel);
  [...]
  return oView;
});
// Master controller
handleApplicantSelect : function (evt) {
    var oHashChanger = sap.ui.core.routing.HashChanger.getInstance();
    var context  = evt.getParameter("listItem").getBindingContext();
    var path = context.getPath();
    var model = this.getView().getModel();
    var item =  model.getProperty(path);
    oHashChanger.setHash("applicants/" + item.id);
},

// Detail controller
onInit: function() {
    this.router = sap.ui.core.UIComponent.getRouterFor(this);
    this.router.attachRoutePatternMatched(this._handleRouteMatched, this);
},

_handleRouteMatched : function(evt){        
    var objectId = evt.getParameter("arguments").id;
    var model = this.getView().getModel();
    var data = model.getData()["applicants"];
    var pathId;

    if (data) {
        for (var i = 0; data.length; i++) {
            if ( objectId == data[i].id ) {
                pathId = i;
                break;
            }
        }

        var sPath = "/applicants/" + pathId;

        var context = new sap.ui.model.Context(model, sPath)
        this.getView().setBindingContext(context);              
    }
},
like image 431
SDD64 Avatar asked May 12 '15 11:05

SDD64


1 Answers

As you've figured out that getData() returns undefined for the first time, which means the model data is still not yet loaded. So you can make use of attachRequestCompleted method of the model & fire an event from the component & listen to that event in the detail controller to ensure the routerPatternMatched() gets executed only after the data is loaded.

//Component.js

var oModel = new sap.ui.model.json.JSONModel("model/mock_applicants.json");

oModel.attachRequestCompleted(jQuery.proxy(function(){
   this.fireEvent("MockDataLoaded"); // fireEvent through component
},this));

oView.setModel(oModel);

//Detail controller

onInit : function(){

this.router = sap.ui.core.UIComponent.getRouterFor(this);  

var oComponent = this.getOwnerComponent();

oComponent.attachEvent("MockDataLoaded",jQuery.proxy(function(){
   this.router.attachRoutePatternMatched(this._handleRouteMatched, this);
},this));

}

Or the simplest & but the dirty way would be to make an synchronous request instead of an async request to load data.

var oModel = new sap.ui.model.json.JSONModel();

oModel.loadData(""model/mock_applicants.json",{bAsync:false});

oView.setModel(oModel);
like image 88
sakthi Avatar answered Sep 18 '22 16:09

sakthi