SAP UI5:master-detail参数传递问题

时间:2016-10-09 14:09:22

标签: json master-detail sapui5

我在SplitApp中将参数从主页面传递到详细信息页面时遇到了一些问题。我使用了一个本地JSON文件,该文件在manifest.json中被指定为模型。

我可以传递一个Object的Id,但在这种情况下,我无法弄清楚,如何在详细视图中接收相应的元素,将它绑定到视图。

我也尝试传递元素的路径,但在这种情况下,在我选择列表项后,url不会改变。

任何想法,我如何在详细信息页面上显示详细信息?

的manifest.json:

...
    "models": {
            "items": {
                "type": "sap.ui.model.json.JSONModel",
                "uri": "model/items.json"
            }
        },
    "routing": {
            "config": {
                "controlId": "rootControl",
                "viewPath": "my.try.view",
                "viewType": "XML",
                "async": true
            },
            "routes" : [
                {
                    "pattern" : "",
                    "name" : "master",
                    "target" : ["detail", "master"]
                },
                {
                    "pattern": "detail/{Id}",
                    "name":"detail",
                    "target": ["master", "detail"]
                }
            ],
            "targets" : {
                "master" : {
                "viewName" : "Master",
                "controlAggregation" : "masterPages"
                },
                "detail" : {
                    "viewName" : "Detail",
                    "controlAggregation" : "detailPages"
                }
            }
        }...

Master.view.xml

<mvc:View controllerName="my.try.controller.Master" xmlns:semantic="sap.m.semantic" xmlns:mvc="sap.ui.core.mvc" xmlns="sap.m">
    <semantic:MasterPage title="Persons">
                    <List id="idList" items="{items>/item}" selectionChange="onItemPressed" mode="SingleSelectMaster">
                        <items>
                            <ObjectListItem title="{item>Date}">
                                <firstStatus>
                                    <ObjectStatus text="{item>Status}"/>
                                </firstStatus>
                            </ObjectListItem>
                        </items>
                    </List>
        </semantic:MasterPage>
</mvc:View>

Master.controller.js

sap.ui.define([
    "sap/ui/core/mvc/Controller",
    "sap/ui/model/json/JSONModel"
    ], function(Controller, JSONModel) {

        "use strict";

        return Controller.extend("my.try.controller.Master", {

        onInit: function() {
            this.oRouter = this.getOwnerComponent().getRouter();
        },

        onItemPressed: function(oEvent) {
        // When I try with the path, nothing happens. Only passing the Id works!?   
        //  var oItemID = oEvent.getParameter("listItem").getBindingContext("items").getPath().substr(1);
            var oItemID = oEvent.getParameter("listItem").getBindingContext("items").getProperty("Id");
            this.oRouter.navTo("detail", {
            Id: oItemID
            });
        }
        });
    });

Detail.view.xml

<mvc:View controllerName="my.try.controller.Detail" xmlns:html="http://www.w3.org/1999/xhtml" xmlns:mvc="sap.ui.core.mvc" xmlns="sap.m" xmlns:semantic="sap.m.semantic">
    <semantic:DetailPage title="Detail">
        <ObjectHeader title="{ItemName}"/>
    </semantic:DetailPage>
</mvc:View>

Detail.controller.js

    sap.ui.define([
        "sap/ui/core/mvc/Controller"
        ], function(Controller) {

            "use strict";

            return Controller.extend("my.try.controller.Detail", {

            onInit: function() {
                this.oRouter = this.getOwnerComponent().getRouter();
                this.oRouter.getRoute("detail").attachPatternMatched(this._onDetailRouteHit, this);
            },

            _onDetailRouteHit: function(oEvent) {

                var sID = oEvent.getParameter("arguments").Id;
//The parameter is passed
                alert(sID);

//This doesn't work. How can I do this withou having a service?
                this.getView().getModel().metadataLoaded().then(function() {
                    var sObjectPath = this.getView().getModel().createKey("ItemSet", {
                        Id : sID
                    });
                    this.getView().bindElement({
                        path: "/" + sObjectPath
                    });
                }.bind(this));
            }   
        });
    });

2 个答案:

答案 0 :(得分:0)

我建议使用ID而不是绑定路径,因为路由URL是可收藏的。使用绑定路径时,所选详细信息可能会在集合更改时更改。

JSONModel没有元数据或键的概念。因此,您必须在模型中搜索项目并自行构建绑定路径:

           _onDetailRouteHit: function(oEvent) {

                var sID = oEvent.getParameter("arguments").Id;
//The parameter is passed
                alert(sID);
                var model = this.getView().getModel("items");

                // If you are not shure if the data has been loaded
                // you should create a promise together with the model,
                // fullfill it in the requestCompleted Event and
                // execute the next lines in its then().

                var array = model.getProperty("/ItemSet");
                for(var i = 0, len=array.length; i<len; i++){
                   if (array[i].Id===sID){
                      this.getView().bindElement({ path: "items>/ItemSet/"+i });
                      break;
                   }
                }
            }   

答案 1 :(得分:0)

尝试在 Component.js 中全局设置模型,绑定上下文可能丢失或路由不匹配,请查看此应用程序,其中显示了如何在主视图和详细视图之间导航{{3 }}

manifest.json

            "routes": [{
            "name": "master",
            "pattern": "",
            "target": ["master"]
        }, {
            "name": "detail",
            "pattern": "masterList/:detailID:",
            "target": ["master", "detail"]
        }, {

Master.view.xml

<mvc:View controllerName="sap.otuniyi.sample.Master" xmlns:mvc="sap.ui.core.mvc" xmlns:core="sap.ui.core" xmlns="sap.m"
xmlns:semantic="sap.m.semantic">
<semantic:MasterPage id="page" title="Contents">
    <semantic:content>
        <List id="list" items="{/masterList}" mode="SingleSelectMaster" 
            noDataText="No List Found" growing="true" growingScrollToLoad="true" selectionChange="onSelectionChange" updateFinished="onUpdateFinished">
            <items>
                <StandardListItem title="{titleName}" type="Active" press="onSelectionChange" icon="{icon}" description="{description}"/>
            </items>
        </List>
    </semantic:content>
</semantic:MasterPage>

Master.controller.js

sap.ui.define( ["sap/ui/core/mvc/Controller", "sap/ui/Device"], function (Controller, Device) {
"use strict";

return Controller.extend("sap.otuniyi.sample.Master", {
    onInit : function () {
        this.getOwnerComponent().getRouter().getRoute("master").attachPatternMatched(this._onRouteMatched, this);
    },
    _onRouteMatched: function(oEvent) {
        if(!Device.system.phone) {
            this.getOwnerComponent().getRouter()
                .navTo("detail", {detailID: 0}, true);              
        }
    },
    onSelectionChange: function(oEvent) {
        var sdetailID = oEvent.getSource().getSelectedItem().getBindingContext().getProperty("detailID");
        this.getOwnerComponent().getRouter()
            .navTo("detail", 
                {detailID:sdetailID}, 
                !Device.system.phone);
    }
});},  true);

Detail.view.xml

<mvc:View xmlns:mvc="sap.ui.core.mvc" xmlns="sap.m" xmlns:layout="sap.ui.layout" controllerName="sap.otuniyi.sample.Detail"
xmlns:semantic="sap.m.semantic">
<semantic:DetailPage id="page" title="{i18n>detailTitle}" navButtonPress="onNavBack">
    <semantic:content>
        <List id="DetailsId" items="{titlesProperties}" headerText="Buttons" updateFinished="onListUpdateFinished"
            noDataText="No detail Data" selectionChange="onSelectionChange" class="sapUiResponsiveMargin">
            <items>
                <StandardListItem title="{subDetailID}" type="Active" press="onSelectionChange"/>
            </items>
        </List>
    </semantic:content>
</semantic:DetailPage>

Detail.controller.js

sap.ui.define( ["sap/ui/core/mvc/Controller", "sap/ui/Device"], function (Controller, Device) {
"use strict";

return Controller.extend("sap.otuniyi.sample", {
    onInit: function() {
        this.getOwnerComponent().getRouter().getRoute("detail").attachPatternMatched(this._onRouteMatched, this);
    },
    _onRouteMatched: function(oEvent) {
        this._detailID = oEvent.getParameter("arguments").detailID;
        this.getView().bindElement("/masterList/" + this._detailID);
    },

    onSelectionChange: function(oEvent) {
        var bReplace = !Device.system.phone;
        var sID = oEvent.getSource().getBindingContext().getProperty("subDetailID");

        this.getOwnerComponent().getRouter().navTo("subDetail", {
            detailID: this._detailID,
            subDetailID: sID
        }, !bReplace);
    }

});}, true);