cancel
Showing results for 
Search instead for 
Did you mean: 

SAPUI5 - SmartTable does not update when binding changes

0 Kudos

Hi,

I am quite new to SAPUI5 and I am supposed to develop an application that consumes a OData service and show the data in a table. Furthermore, I also need to be able to make updates to the OData.

I have no prior knowledge to SAPUI5 - I basically just got asked to use SAPUI5 and then I was on my own. So I have tried to do some tutorials at www.sapui5.hana.ondemand.com/ and just follow a "trial and error" approach.

Now, I am able to retrieve data from the OData service (a service my organisation has given me) and show it in a SmartTable in a second view. The user chooses the entityset and so on he wants to have displayed and then the view changes to the smarttable. This works the first time you try. However, if you navigate back to the previous view to change the setting and try again, the table doesnt refresh. I feel like I have tried everything, and I just cant seem to make it work. If I get this to work, I feel like I will also be able to implement a much better way to update the odata, than what you can see in my code.

The first view:

home.view.xml

The code for this view:

home.controller.js
sap.ui.define([
	"DemoApplication/controller/BaseController",
	"sap/m/MessageToast"
], function(BaseController, MessageToast) {
	"use strict";


	return BaseController.extend("DemoApplication.controller.Home", {


		onInit: function() {


			//Get fields
			this.apiURLComboBox = this.getView().byId("selectedAPI");
			this.instanceInputField = this.getView().byId("selectedInstance");
			this.usernameInputField = this.getView().byId("selectedUsername");
			this.passwordInputField = this.getView().byId("selectedPassword");
			this.tableComboBox = this.getView().byId("selectedTable");
			this.selectedParameters = this.getView().byId("selectedParameters");
			this.requestTableButton = this.getView().byId("requestTableButton");


			//Initiate variables
			this.oDataModel;
			this.JSONModel = new sap.ui.model.json.JSONModel();
			this.JSON = {};
			this.entitySets;
			this.entityProperties;
			this.visibleEntityFields;
			this.invisibleEntityFields;
		},


		//Eventhandler when the Refresh button is pushed
		refreshTables: function(oEvent) {


			//Destroy items inside Table ComboBox
			this.tableComboBox.destroyItems();


			try {


				//Retrieve oDATA with the selected API URL and entered instance, username and password
				this.oDataModel = new sap.ui.model.odata.ODataModel(this.apiURLComboBox.getSelectedKey(), true, this.usernameInputField.getValue() +
					"@" + this.instanceInputField.getValue(),
					this.passwordInputField.getValue());
					
				//Get EntitySets 
				this.entitySets = this.oDataModel.getMetaModel().getODataEntityContainer(false).entitySet;


				//For loop that adds the entity names into the Table ComboBox
				for (var i = 0; i < this.entitySets.length; i++) {


					this.tableComboBox.addItem(new sap.ui.core.Item({
						text: this.entitySets[i].name,
						key: this.entitySets[i].name
					}));


				}


			} catch (err) {
				MessageToast.show("Could not retrieve tables.\nPlease check your login informations.");
			}
		},


		//Eventhandler when a table is choosed
		tableChoosed: function(oEvent) {


			//Empty the selected parameters, if any where selected
			this.selectedParameters.destroyItems();


			//Set Button text
			this.requestTableButton.setText("Request " + this.tableComboBox.getSelectedKey());


			//Get the selected table key
			var sEntity = this.tableComboBox.getSelectedKey();
			


			//Go enter the oDATA and get the properties of the selected entity
			this.entityProperties = this.oDataModel.oMetadata._getEntityTypeByPath(sEntity).property;
			


//this.oDataModel.read(sEntity + "(" + this.oDataModel.oMetadata._getEntityTypeByPath(sEntity).key +  ")", {success: this.suc, error: this.err});


			//Instantiate visible fields with an array containing the length of the amount 
			//of properties(columns) the entity has.
			this.visibleEntityFields = Array(this.entityProperties.length);


			//Instantiate empty array for invisible fields
			this.invisibleEntityFields = Array();


			//Check whether the column is visible or not.
			for (var i = 0; i < this.entityProperties.length; i++) {
				
				//If visible, add it as a visible field and create an item into the Parameters MultiBox
				if (this.entityProperties[i].extensions[4].value === "true") {
					this.visibleEntityFields[i] = this.entityProperties[i].name;


					this.selectedParameters.addItem(new sap.ui.core.Item({
						text: this.entityProperties[i].name,
						key: this.entityProperties[i].name
					}));


				//If not visible, add it to the invisible array
				} else {
					this.invisibleEntityFields.push(this.entityProperties[i].name);


				}
			}


		},
/*		suc : function(data){
			alert("hej" + data);
		},
		
		err : function(data){
						alert("hej");
						console.log(data);


		},
*/	


		//Get router function
		getRouter: function() {
			return sap.ui.core.UIComponent.getRouterFor(this);
		},


		//Display not found function
		onDisplayNotFound: function(oEvent) {
			//Display the notFound target without changing the hash
			this.getRouter().getTargets().display("notFound", {
				fromTarget: "home"
			});
		},


		//Navigate to third page --> not used atm.
		onNavToPerPersonal: function(oEvent) {
			this.getRouter().navTo("perPersonal");
		},


		//Navigate to the table view
		onNavToTableView: function(oEvent) {


			//Fill the JSON variable with the values selected
			this.JSON.apiURL = this.apiURLComboBox.getSelectedKey();
			this.JSON.instance = this.instanceInputField.getValue();
			this.JSON.username = this.usernameInputField.getValue();
			this.JSON.password = this.passwordInputField.getValue();
			this.JSON.table = this.tableComboBox.getSelectedKey();
			this.JSON.chosenEntityFields = this.selectedParameters.getSelectedKeys();
			this.JSON.visibleEntityFields = this.visibleEntityFields;
			this.JSON.invisibleEntityFields = this.invisibleEntityFields;


			//Add the JSON to the JSONModel and refresh
			this.JSONModel.setData(this.JSON);
			this.JSONModel.refresh(true);


			//Set the oDATA model to the core and refresh
			sap.ui.getCore().setModel(this.oDataModel, 'oDataModel');
//			sap.ui.getCore().getModel('oDataModel').refresh(true);


			//Set the JSON model to the core and refresh
			sap.ui.getCore().setModel(this.JSONModel, 'JSONModel');
//			sap.ui.getCore().getModel('JSONModel'); 


			//Change the view
			this.getRouter().navTo("tableView");


		},


		onExit: function() {
		//	sap.ui.getCore().getModel('JSONModel').refresh(true);
		//	sap.ui.getCore().getModel('oDataModel').refresh(true);
		}


	});


});

I am not quite sure if I have understood how you work with a odatamodel and setting it as a model for the core and so on, however this works and it updates the second view:

TableViewContent.view.js

You can see that the Country table is loaded in the table at the bottom of the image. Ignore the panels over the table 😄

TableViewContent.controller.js

sap.ui.define([
	"DemoApplication/controller/BaseController",
	"sap/ui/model/json/JSONModel",
	"DemoApplication/model/formatter",
	"sap/ui/model/Filter",
	"sap/ui/model/FilterOperator"


], function(BaseController, JSONModel, formatter, Filter, FilterOperator) {
	"use strict";


	return BaseController.extend("DemoApplication.controller.table.TableViewContent", {


		formatter: formatter,


		onInit: function() {
			this.smartTable = sap.ui.getCore().byId("smarttable");
			
		},


		onBeforeRendering: function() {
			
//________________________________________________________________
			var JSONModel = sap.ui.getCore().getModel('JSONModel');
		//	console.log(JSONModel);
			JSONModel.refresh(true);
		//	console.log(JSONModel);


			//Get the URI
			var sURI = JSONModel.oData.apiURL;
			this.oDataModel = new sap.ui.model.odata.ODataModel(sURI, true, JSONModel.oData.username + "@" +
				JSONModel.oData.instance, JSONModel.oData.password); 


			//Table chosen
			var sEntity = JSONModel.oData.table;


			//Fields to show
			var visibleEntityFields;


			//Checks whether the user have checked any specific columns or want all displayed.
			if (JSONModel.oData.chosenEntityFields.length === 0) {
				visibleEntityFields = JSONModel.oData.visibleEntityFields;
			} else {
				visibleEntityFields = JSONModel.oData.chosenEntityFields;
			}


			//Set header
			this.smartTable.setHeader(sEntity);
		
			//Set entity set
			this.smartTable.setEntitySet(sEntity);


			//Set visible fields
			this.smartTable.setInitiallyVisibleFields(visibleEntityFields);
			
			//Set ignored fields, which are the fields not allowed to call
			this.smartTable.setIgnoredFields(JSONModel.oData.invisibleEntityFields);


			//Set model
			this.smartTable.setModel(this.oDataModel);
			this.getView().setModel(this.oDataModel);
			//	this.smartTable.getBinding("columns").refresh(true);
			//	this.smartTable.getBinding("items").refresh(true);
			//  this.smartTable.getModel().refresh(true);
			//  this.smartTable.rebindTable(true);
			
			this.getView().getModel().refresh();
			this.smartTable.getModel().updateBindings();


		},


		onExit: function() {
			this.chosenParameters.length = 0; //Empty array
		//	this.smartTable.getBinding().destroy();
			//	
		this.smartTable.exit();
		this.oDataModel.stop();


		}


	});


});

Please ignore all of the code commented out. It is just because I have tried different approaches and couldn't make anything work. Problem is now, when I push the arrow back to the previous view, choose another table or try to change any other field and come back to this view, only the header name of the table changes, but the columns and the loaded items stay the same:

I am sorry for this very long post, but I feel that you need all the code to be able to pinpoint what I am doing wrong.. I would really appreciate it, if soembody had the time to take a look and give me some help or directions.

Thank you very much in advance.

Best regards,

Emil

Accepted Solutions (0)

Answers (1)

Answers (1)

alexd
Advisor
Advisor

Hello,

In case you still have this issue, I have managed to solve the same problem by using the rebindChart(); method.

var chart = this.getView().byId("ItemsSmartChart"); 

chart.setEntitySet("X");

chart.rebindChart();