Binding nested JSON to XML View

This is the example I'm trying to make work:

Manifest model declaration:

"models": {
   "caixas": {
        "type": "sap.ui.model.json.JSONModel",
        "uri": "Caixas.json"
    }
}

Caixas.json file:

{"Caixas": [
    {
        "NomeCaixa": "PETROBRAS",
        "Valores": [
            {
                "LabelValor": "Saldo Inicial",
                "ValorValor": 3520,
                "MoedaValor": "JPY"
            },
            {
                "LabelValor": "Entrada",
                "ValorValor": 3520,
                "MoedaValor": "JPY"
            }
        ]
    },
    {
        "NomeCaixa": "PEBEM",
        "Valores": [
            {
                "LabelValor": "Saldo Inicial",
                "ValorValor": 3520,
                "MoedaValor": "JPY"
            },
            {
                "LabelValor": "Entrada",
                "ValorValor": 3520,
                "MoedaValor": "JPY"
            }
        ]
    }
]}

The problem is:

I have a SplitApp where the master page is binding to "Caixas" level of the Caixas.json file. This part is working.

When I click at the master page to select one of the items, the details page should show the details of the currently selected "Caixas". This is working for the attribute "NomeCaixa", since it's directly related to "Caixas" level.

The thing is that I would like to display a list with the data inside "Valores" array for the selected Caixa.

If I bind to a harcoded "Caixas" like in:

<List id="caixasList" 
      class="sapUiResponsiveMargin"
      headerText="Caixas" 
      width="auto" 
      mode="SingleSelectMaster"
      items="{caixas>/Caixas/0/Valores}">
    <items>
        <ObjectListItem title="banana" />
    </items>
</List>

it works fine, but it always will show the first "Caixas" "Valores" array values.

I wish to write a path in the items attribute of the element List so that it displayed the "Valores" array values of the currently selected "Caixas" on the master page.

I've tried several combinations using >/ etc and also tried finding a comprehensive guide for this path syntax, but could not get any help.

Can you please, help me?

3 answers

  • answered 2018-01-09 14:57 Francesco Iannazzo

    just try binding to the following . Your JSON is a List in another List. Bind the first element absolutely {caixas>/Caixas} and then afterwards only relative {caixas>Valores} without slash.

    <List id="caixasList" 
               class="sapUiResponsiveMargin"
               headerText="Caixas" 
               width="auto" 
               mode="SingleSelectMaster"
               items="{caixas>/Caixas}">
    
            <items>
    
                <List
                   items="{caixas>Valores}"
                >
               <items>
                  <ObjectListItem
                     title="{caixas>LabelValor}"
    
                  </ObjectListItem>
              </items>
            </List>
    
            </items>
    
         </List>
    

  • answered 2018-01-09 14:57 Andrii Naumovych

    You need to bind your detail page to the currently selected "Caixas" object via "bindObject". Then from now on, you are able to define relative binding on the detail page, it will look like this:

    items="{caixas>Valores}"

    in this line, "caixas" means the name of the model, but not the name of the property in JSON source data.

  • answered 2018-01-09 14:57 Péter Cataño

    Plunker Concept

    The view structure and interaction should be:

    1. SplitApp with one mesterPage on the left side showing list of Caixas
    2. SplitApp with one detailPage for each caixa with a list of its Valores
    3. By clicking a masterPage List item, app navigates to the appropriate detail page with SplitApp.toDetail

    To render the desired master and detail pages iterate over Caixas array: (Implementation sketch, based on SplitApp Sample):

    Controller.js (part):

    onInit: function() {
        var splitAppObj = this.byId("SplitAppDemo");
        var masterList = this.getView().byId('masterList');
        var caixa, page, list, listItem, valor;
        for (var i = 0; i < this._jsonModel.oData['Caixas'].length; i++) {
            caixa = this._jsonModel.oData['Caixas'][i];
            // Add item to master list
            listItem = new sap.m.StandardListItem({
                title: caixa['NomeCaixa'],
                type: "Active",
                customData: new sap.ui.core.CustomData({key: 'to', value: 'page' + i})
            });
            masterList.addItem(listItem);
            // Create and add detail page with list content
            page = new sap.m.Page(
                {id: this.createId('page' + i), title: caixa['NomeCaixa']});
            list = new sap.m.List();
            for (var j = 0; j < caixa['Valores'].length; j++) {
                valor = caixa['Valores'][j];
                listItem = new sap.m.StandardListItem({
                    title: valor['LabelValor']
                });
                list.addItem(listItem);
            }
            page.addContent(list);
            splitAppObj.addDetailPage(page);
        }
    },
    onListItemPress: function(oEvent) {
        var sToPageId = oEvent.getParameter("listItem")
            .getCustomData()[0].getValue();
    
        this.byId("SplitAppDemo").toDetail(this.createId(sToPageId));
    }
    

    View.xml (part):

    <SplitApp id="SplitAppDemo" initialMaster="master">
        <detailPages></detailPages>
        <masterPages>
            <Page id="master" title="Master" icon="sap-icon://action">
                <content>
                    <List id="masterList" itemPress="onListItemPress">
                        <items></items>
                    </List>
                </content>
            </Page>
        </masterPages>
    </SplitApp>