Skip to Content
0

UI5 : No context after passing parameters (navigation) / values not shown

Apr 09, 2017 at 11:19 AM

223

avatar image

Since days I`m stucked with parameter based navigation from an overview- to an detailpage. The navigation itself is working fine but the values of the detailpage are not being displayed in the detailpage (ShowObject). I think its somehow related to the binding in the detail controller.

Please find codesnippets attached:

Manifest.json

"routes": [
            {
                "pattern": "ShowObject/{Code}",
                "name": "ShowObject",
                "target": "ShowObject"
            },

Overview.controller.js Triggered navigation by clicking selecting line item and clicking on edit button. Result is the value of the column "code" (e.g. "ABC").

onEditButtonPressed:function() {

        var oTable = this.getView().byId("idTable");
        var oCode = oTable.getSelectedItem().getBindingContext("model").getProperty("Code");
        var oRouter = this.getOwnerComponent().getRouter();

        oRouter.navTo("ShowObject", {
            Code: oCode
        }); 
    },

ShowObject.controller.js Attach route pattern and set binding context

onInit: function() {

            var oRouter = sap.ui.core.UIComponent.getRouterFor(this);
            oRouter.getRoute("ShowObject").attachMatched(this._onRouteMatched, this); 

        },
            _onRouteMatched: function (oEvent) {

                var oView = this.getView();

                oView.bindElement({
                    path: "/Entity/" + "('" + oEvent.getParameter("arguments").Code + "')",
                    model: "model"

                    });
            },

The console output of the binding path is: /Entities('ABC')

To access a single entity in the browser following path would be required:https://domainname.com/service/Service.svc/Entities('ABC')

The detailview contains simple text fields.

<f:content>
    <Label text="Code"/>
    <Text value="{model>Code}"/>
    <Label text="Lastname" />
    <Text value="{model>Lastname}"/>
</f:content>

Edit: Modelname was incorporated. 

As data source I`m using an odata service which is on version 4.

I also tried to get the context by passing paramters using getPath() approach described in this code example. Plunker GetPath But the result is the same. The navigation is working but no values are being shown in the text fields.

Now I was thinking about creating an object based on the passed path or the property of the field "Code". Does it make sense to go this way. Can somebody guide me accordingly?

Thank you

MR

10 |10000 characters needed characters left characters exceeded
* Please Login or Register to Answer, Follow or Comment.

7 Answers

Jun Wu Apr 09, 2017 at 12:26 PM
0

if your model got name, all your binding needs that name

<f:content><Label text="Code"/><Textvalue="{model>Code}"/><Label text="Lastname" /><Textvalue="{model>Lastname}"/></f:content>
Show 6 Share
10 |10000 characters needed characters left characters exceeded

HI Jun,

Thank you for having a look. I set the binding according to your suggestions but the result is the same - no data are shown.

Furthermore, I created a table within the detail view and bound the context to it. For my suprise the same data are shown in the table like in the overview page.

Further ideas?

BR

Matthias

0
Matthias Reichel
path:"/Entity/" + "('" + oEvent.getParameter("arguments").Code + "')",

did u check this? it doesn't look good to me.

0

For me it is looking ok. Do you mean the fact that parts of the path are hardcoded?

I also tried it another way using following approach. Without hardcoding anything. Hereby I used "Entity" and "Code" as parameters being passed. Navigation to the detail page is working again but no data are shown up.

ShowObject.controller.js:

onInit: function() {
				
				var oRouter = sap.ui.core.UIComponent.getRouterFor(this);
				oRouter.getRoute("ShowObject").attachMatched(this._onRouteMatched, this); 
				
			},
				_onRouteMatched: function (oEvent) {
				
					var oView = this.getView();
			
					oView.bindElement({
						path: oEvent.getParameter("arguments").Entity + "/" + oEvent.getParameter("arguments").Code
					
					});


				}, 

0
Matthias Reichel
it should be something like this.
/Entities(YOURID)


what is your string? got it?

0

I checked it for both approaches in the codesnippet.

For first one the output was:

/Entities(EUR) --> Hereby EUR is the property of the field "Code" which is declared as the key property in the backend. I also added ' ' so the output was /Entities('EUR').

In the second one I referred to the index of the table by using getPath() so it was /Entities/1 (e.g. for selection of the second line in the table). I also changed it to /Entities(1)


Still no luck; As both approaches are not working. What else can I use as ID to access a single entity?

0
Matthias Reichel
_onRouteMatched

1.in this method, can you check if you are able to access the model?

2. under /Entities(YOURID), you really have attributes:Code, Lastname?
0
Jun Wu Apr 10, 2017 at 12:22 AM
-1

are u using jsonmodel or odata model?

paste all your code here. and data structure

Share
10 |10000 characters needed characters left characters exceeded
Akhilesh Upadhyay Apr 10, 2017 at 05:58 AM
0

where and how have defined model ?

is GET_ENTITY method is implemented in data provider class ? check console and share if any errors

path should be :

oView.bindElement({
    path: "/Entities('" + oEvent.getParameter("arguments").Code + "')"
});
Share
10 |10000 characters needed characters left characters exceeded
Matthias Reichel Apr 10, 2017 at 08:16 AM
0

It is an odata model v4 .The model is defined in the manifest using a datasource.

"dataSources": {		
                          "manageservice": {
				"uri": "/destinations/testmodel/Service.svc/",
				"type": "OData",
				"settings": {
					"odataVersion": "4.0"
				},

"models": {
			"model": {
				"dataSource": "manageservice",
				"settings": {
					"synchronizationMode": "None",
					"operationMode": "Server",
					"groupId": "$direct"
				}

If I start my application all data are shown in the overview page. So in general the model is working correctly. Also if I navigate to the respective detail views I found following response in the network tab.

{"@odata.context":"$metadata#Entities","Code":"ABC","Name":"Sinclair"}

To check if "getentity" is working I simply accessed a single entity within the browser by using some kind of this URL:

https://domainname.com/service/Service.svc/Entities('ABC')

The entity(structred in xml) is looking like this:

<a:entry xmlns:a="http://www.w3.org/2005/Atom" xmlns:m="http://docs.oasis-open.org/odata/ns/metadata" xmlns:d="http://docs.oasis-open.org/odata/ns/data" m:context="$metadata#Entities">
<a:id>Entity(79b26e9a-b8e6-4d00-9fce-eb45c1a8a51b)</a:id>
<a:title/>
<a:summary/>
<a:updated>2017-04-10T08:08:37Z</a:updated>
<a:author>
<a:name/>

</a:author>

<a:link rel="edit" href="Entity(79b26e9a-b8e6-4d00-9fce-eb45c1a8a51b)"/>
<a:category scheme="http://docs.oasis-open.org/odata/ns/scheme" term="#OData.entity.entity"/>
<a:content type="application/xml">
<m:properties>
<d:Code>ABC</d:Code>
<d:Lastname>Sinclair</d:Lastname>

</m:properties>

</a:content>

</a:entry>

I still don`t get it why the context is not showing in respective fields of the detail view.

Share
10 |10000 characters needed characters left characters exceeded
Akhilesh Upadhyay Apr 10, 2017 at 02:38 PM
0

as per details you have provide only below has to be corrected:

  1. "/Entities('" + oEvent.getParameter("arguments").Code + "')"
  2. model name while element binding in details view ( you have incorporated now)
  3. if still not working then, you can get that named model in onInit of details view controller and set back that model to detail view individually.

OR

  1. remove model name from manifest file
  2. Remove model reference from every bindings (first and second view)
  3. and in details view bindElement like below:
oView.bindElement({
   path: "/Entities('" + oEvent.getParameter("arguments").Code + "')",
   //model: "model" //remove this line
});
"models": {
    "": { // remove 'model' from here and keep blank
    "dataSource": "manageservice",
    "settings": {
              "synchronizationMode": "None",
               "operationMode": "Server",
               "groupId": "$direct"
             } 
...........

if no luck, paste your all code including component, first controller and details code.

Share
10 |10000 characters needed characters left characters exceeded
Matthias Reichel Apr 11, 2017 at 10:07 AM
0

I followed up on the suggestions removing the model name. Also the first approach didn`t work. For testing purposes I bound a table to the detail view and data were shown but without any context. Of course the text fields can display then data for a selected entity.

Please find my code involved in the routing:

Component.js

sap.ui.define([
	"sap/ui/core/UIComponent",
	"sap/ui/Device",
	"testapplication/model/models"
], function(UIComponent, Device, models) {
	"use strict";

	return UIComponent.extend("trmaccelerator.Component", {
		metadata: {
			manifest: "json"
		},

		init: function() {
			// call the base component's init function
			UIComponent.prototype.init.apply(this, arguments);

			// set the device model
			this.setModel(models.createDeviceModel(), "device");
			
			// initialize router to create views based on url/hash 
			this.getRouter().initialize();
		}
	});
});

Manifest.json including Data Source, Model and Routing

"dataSources": {
	"source": {
		"uri": "/destinations/service/Service.svc/",
		"type": "OData",
		    "settings": {
		         "odataVersion": "4.0"
		     }
	}			
},

"models": {
	"model": {
		"dataSource": "source",
		"settings": {
			"synchronizationMode": "None",
			"operationMode": "Server",
			"groupId": "$direct"
	   }			
},

"routing": {
			"config": {
				"routerClass": "sap.m.routing.Router",
				"viewType": "XML",
				"viewPath": "trmaccelerator.view",
				"controlId": "idApp",
				"controlAggregation": "pages",
				"bypassed": {
					"target": "Error"
				},
				"async": true,
				"transition": "show"
			},
			"routes": [
				{
					"pattern": "",
					"name": "DisplayOverview",
					"target": "DisplayOverview"
				},
				
				{
					"pattern": "ShowObject/{Code}",
					"name": "ShowObject",
					"target": "ShowObject"
				}
				
			],
			"targets": {
				
				"DisplayOverview": {
					"viewName": "DisplayOverview",
					"viewId": "idDisplayOverview",
					"viewLevel": 1
				},
				"ShowObject": {
					"viewName": "ShowObject",
					"viewId": "idShowObject",
					"viewLevel": 2,
					"transition": "slide"
				},
			}
}

DisplayOverview.js

sap.ui.define([
	"sap/ui/core/mvc/Controller",
	"sap/ui/model/Filter",
	"sap/ui/model/FilterOperator",
	"sap/m/MessageToast"
	
	], function(Controller, Filter, FilterOperator, MessageToast) {
	"use strict";


	return Controller.extend("trmaccelerator.controller.DisplayOverview", {

	       onEditCurrencyButtonPressed:function(oEvent) {
		
			var oTable = this.getView().byId("idTableCodes");
			var oCode = oTable.getSelectedItem().getBindingContext("model").getProperty("Code");
			var oRouter = this.getOwnerComponent().getRouter();
			
			oRouter.navTo("ShowObject", {
				Code: oCode
			}); 
	      },	 
	});
});

DisplayOverview.xml

<mvc:View	controllerName="trmaccelerator.controller.DisplayOverview"
			xmlns:core="sap.ui.core" 
			xmlns:mvc="sap.ui.core.mvc" 
			xmlns="sap.m" 
			xmlns:html="http://www.w3.org/1999/xhtml"
			xmlns:l="sap.ui.layout"
			xmlns:f="sap.ui.layout.form"
			xmlns:fb="sap.ui.comp.filterbar">


	<App>
		<pages>
			<Page title="Overview">
				<content>
			
                                                 <Table	id="idTableCodes" 
							mode="SingleSelectLeft" 
							items="{ path: 'model>/Entities' }">
						
						<headerToolbar>
							<Toolbar>
								<Title text="Codes"/>
								<ToolbarSpacer></ToolbarSpacer> 
								<Button text = "Edit" press="onEditCurrencyButtonPressed" enabled = "true"/> 	
							</Toolbar>
						</headerToolbar>
						<columns>
						
							<Column>
								<Text text="Code"/>
							</Column>
							<Column>
								<Text text="Lastname"/>
							</Column>
				
						</columns>
						<items>
	                                               <ColumnListItem >
								<cells>
									<ObjectIdentifier text="{Code}"/>
									<Text text="{Name}"/>
								</cells>
							</ColumnListItem>
						</items>
					</Table>
				</content>
			</Page>
		</pages>
	</App>
</mvc:View>


ShowObject.js

onInit: function() {
	var oRouter = sap.ui.core.UIComponent.getRouterFor(this);
	oRouter.getRoute("ShowObject").attachMatched(this._onRouteMatched, this); 
},
			
	_onRouteMatched: function (oEvent) {
                       var oView = this.getView();
		       var oPath =  "/Entities('" + oEvent.getParameter("arguments").Code + "')";

                        oView.bindElement({
				path: oPath,
				model: "model"
			});					
	},

ShowObject.xml

<mvc:View	controllerName="trmaccelerator.controller.ShowObject"
			xmlns:html="http://www.w3.org/1999/xhtml" 
			xmlns:mvc="sap.ui.core.mvc"
			xmlns="sap.m"
			xmlns:l="sap.ui.layout"
			xmlns:f="sap.ui.layout.form"
			xmlns:core="sap.ui.core" >
	<App>
		<pages>
			<Page title="Change Codes"
			showNavButton="true"
			navButtonPress="onCurrencyBackButtonPressed"> 
		
				<VBox class="sapUiSmallMargin">
					<f:SimpleForm id="idForm"
						minWidth="1024"
						maxContainerCols="2"
						editable="false"
						layout="ResponsiveGridLayout"
						title="Change Codes"
						labelSpanL="2"
						labelSpanM="2"
						emptySpanL="0"
						emptySpanM="0"
						columnsL="1"
						columnsM="1">
						<f:content>
							<Label text="Currency ISO code"/>
							<Text value="{model>Code}"/>
							<Label text="Currency description" />
							<Text value="{model>Lastname}"/>
						</f:content>
					</f:SimpleForm>
				</VBox>
			</Page>
		</pages>
	</App>
</mvc:View>
Share
10 |10000 characters needed characters left characters exceeded
Akhilesh Upadhyay Apr 12, 2017 at 09:57 AM
0

I am surprised you are getting data displayed in table of DisplayOverview view even binding is not correct.

check my observations below:

1: in DisplayOverview view binding should be with model name like {model>Code},

2: in ShowObject.js try with attachPatternMatched

try: oRouter.getRoute("ShowObject").attachPatternMatched(this._onRouteMatched, this);

may help

Share
10 |10000 characters needed characters left characters exceeded