Search code examples
sapui5

How to get object key when using aggregation binding in OpenUI5


For example, I have an sap.ui.model.json.JSONModel initialized with the following data:

{
    "data": {
        "something": {"a": "blah", "b": "blah", "c": "blah"},
        "another": {"a": "blah", "b": "blah", "c": "blah"}
    }
}

And I have a sap.m.List in XMLView like this:

<List items="{/data}">
    <items>
        <ObjectListItem title="{a}" intro="">
            <firstStatus>
                <ObjectStatus title="{b}" text="{c}"/>
            </firstStatus>
        </ObjectListItem>
    </items>
</List>

Now I want the intro property of these two ObjectListItem to be "something" and "another", but I can't find a way to do it except changing the data to

{
    "data": {
        "something": {"key": "something", "a": "blah", "b": "blah", "c": "blah"},
        "another": {"key": "another", "a": "blah", "b": "blah", "c": "blah"}
    }
}

and then bind "{key}", which seems pretty stupid (it introduces redundancies and wastes server bandwidth).

So, any idea?


Solution

  • Using a custom factory function, getting the key you want from the context path:

    <!DOCTYPE html>
    <html>
    	<head>
    		<meta http-equiv='X-UA-Compatible' content='IE=edge'>
    		<meta charset="utf-8">
    
    		<title>MVC with XmlView</title>
    
    		<!-- Load UI5, select "blue crystal" theme and the "sap.m" control library -->
    		<script id='sap-ui-bootstrap'
    				src='https://sapui5.hana.ondemand.com/resources/sap-ui-core.js'
    			data-sap-ui-theme='sap_bluecrystal'
    			data-sap-ui-libs='sap.m'
    			data-sap-ui-xx-bindingSyntax='complex'></script>
    
    		<script id="view1" type="sapui5/xmlview">
    		    <mvc:View
    				controllerName="my.own.controller"
    				xmlns:l="sap.ui.layout"
    				xmlns:core="sap.ui.core"
    				xmlns:mvc="sap.ui.core.mvc"
    				xmlns:f="sap.ui.layout.form"
    				xmlns="sap.m">
    			    <List items="{path:'/data', factory: '.myFactory'}">
              </List>
    			</mvc:View>
    	</script>
    
    
    		<script>
    			// define a new (simple) Controller type
    			sap.ui.controller("my.own.controller", {
    			  myFactory: function(sId, oContext){
    			    var keyPath = oContext.getPath();
    			    console.log(oContext);
    			    
    			    var oObjectListItem = new sap.m.ObjectListItem({
    			      title: {path: keyPath + '/a'},
    			      intro: keyPath.split('/')[keyPath.split('/').length - 1],
    			      firstStatus: [
    			        new sap.m.ObjectStatus({
    			          title: {path: keyPath + '/b'},
    			          text: {path: keyPath + '/c'}
    			        })
    			      ]
    			    });
    			    
    			    return oObjectListItem;
    			  }
    			});
    
    			// instantiate the View
    			var myView = sap.ui.xmlview({viewContent:jQuery('#view1').html()}); // accessing the HTML inside the script tag above
    
    			// create some dummy JSON data
    			var data = {
              "data": {
                  "something": {"a": "blah", "b": "blah", "c": "blah"},
                  "another": {"a": "blah", "b": "blah", "c": "blah"}
              }
          }
    			
    			// create a Model and assign it to the View
    			var oModel = new sap.ui.model.json.JSONModel();
    			oModel.setData(data);
    			myView.setModel(oModel);
    			
    			
    			// put the View onto the screen
    			myView.placeAt('content');
    
    		</script>
    	
    	</head>
    	<body id='content' class='sapUiBody'>
    	</body>
    </html>