SAPUI5中的路由:如何实现URL的传递?模型数据未初始加载

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

我的目标是编写一个具有路由支持的 SAPUI5 Fiori 应用程序。一个邮件目标是让 URL 过得去。例如在像 "please approve this: link" 这样的电子邮件中。 link 是与我的路由配置匹配的 URL,例如 index.html#/applicants/8.

我使用的是一种典型的 sap.m.SplitApp 应用程序。单击 masterview 中的列表项会将 URL 更改为 index.html#/applicants/[id of entry in JSON]。我可以单击列表,我定义的路线正在匹配并且应用程序按预期加载(申请人)数据。

但是,我的问题来了,这在直接使用 URL 时不起作用,比如将 [my url]/index.html#/applicants/8 粘贴到我的浏览器中。该应用程序已启动,但未加载详细数据。我必须再次单击另一个列表项才能获取数据。

实际上,传递URL时调用了控制器,但似乎模型未启动且未定义。我的 JSON 模型绑定在 Component.js

createContent 函数中

// 更新时间 2015-05-14 问题似乎与 getData() 函数有关。我有模型,它有条目,但是 getData() returns undefined 第一次加载我的应用程序。我最近读到 getData() 已弃用。我应该如何改进下面的编码?

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

正如您第一次发现 getData() returns 未定义,这意味着模型数据仍未加载。因此,您可以使用模型的 attachRequestCompleted 方法并从组件中触发一个事件并在细节控制器中侦听该事件,以确保仅在加载数据后才执行 routerPatternMatched()。

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

//详细控制器

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

}

或者最简单的 & 但肮脏的方法是发出同步请求而不是异步请求来加载数据。

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

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

oView.setModel(oModel);