SAPUI5 - Remove oData Model bound to view - sapui5

I am new to SAPUI5 and I am very much in need of your help.
I have created an XML view and bound an OData model to it like below. Now all the controls in the view got bound and I am able to see the data.
this.getView().setModel(oModel);
Now I have a requirement in which I have to completely remove this binding from the view. I destroyed the oModel and removed all its bindings. And now when I refresh the view, the data still exists in the screen. I want all the data from the view to disappear.
oModel.destroy();
oModel.refresh();
this.getView().getModel().refresh(true);

I assume that you're using an sap.ui.model.odata.ODataModel to retrieve odata, then done binding using, for example, a JSON model, like so,
var oJson = new sap.ui.model.json.JSONModel({data : oData);
/* Here 'data' is any name that you provide to identify your data model,
'oData' is the data that is received as response from the sap.ui.model.odata.ODataModel */
And set this model to the view like you have mentioned,
this.getView().setModel();
Now, to remove this data from the view you can try the following,
oJson.setData({data : null}, true);
This would set the previously set oData to null and therefore all data binding from the controls in the view would be removed(changed to null).
I believe oJson.refresh() is optional, but you can try adding that as well if the change is not reflected.
Its an approach until may be you find something better :) Here is the documentation for the APIs that I've used.

If you are using
var dataModel = new sap.ui.model.json.JSONModel();
dataModel.setData(oDataResponse); //Data returned from oData.Read()
this.getView().setModel(dataModel, "dataModel");
Retrieve the model, Set the model to null, Update the binding
var dataModel = this.getView().getModel("dataModel");
if(dataModel){
dataModel.setData(null);
dataModel.updateBindings(true);
}

Related

SAPUI5 Smart Table inside a dialog

I've a sapui5 application which has several controls in my page.
Such as Tables , Calendar etc.
And I've create a singe model for my page in the onInit event as follows
var viewModel = new JSONModel();
//Prepare Initial Model
viewModel.setData({
LineDetails: [],
Calendar: {},
PageMode: "add",
DateStart: new Date(),
DateEnd: new Date(),
IsHistoryAvailable: false
});
this.getView().setModel(viewModel);
What I need to do is, I've to include a Smart Table inside a dialog in this page.
The dialog will open once I click a button in the page.
How can I bind data to the smart table inside the dialog?
I only have experience of binding the model to a smart table which either declaring default model in the manifest or in the page.
But here I've already added a model to the page in the onInit event.
So how can I bind data?
Is there a way to bind smart table to a Property which included in the above declared model.
Propert name : SmartTableModel
eg :
viewModel.setData({
SmartTableModel:[]
LineDetails: [],
Calendar: {},
PageMode: "add",
DateStart: new Date(),
DateEnd: new Date(),
IsHistoryAvailable: false
});
Per default, the data you want to bind must come from an ODataModel which is the default model! In other words: you can't simply bind data from some JSONModel, and you can't bind data to a SmartTable which comes from a named model (even if it's and ODataModel).
SmartTable only works with data from an ODataModel, thus you can't work with JSonModels
Currently, SmartTable only works with dafault models (""), i.e. named model won't work
I'm afraid to tell you that what you want does not work as of today. You could use the MockerServer + annotations in your real app code (not onbly for testing) as a workaround, but I think I would avoid that. There are some other tricks as well, you could start reading here: SAP UI5 :named json model with smart table

Best practice to lazy load data on tab click

Within the onBeforeRendering() function of a view how should I determine if a specific node is present in the model and modify the model to include the node if not? This question is about lazy loading of data to the model for data that will be infrequently accessed by users but would have a performance penalty if loaded with initial model data.
My use case has a list page leading to a detail page for whatever item in the list the use clicks. On the detail page is a set of tabs which expose sub-details related to the selected detail. Specifically a long text description of a the brief for a task.
The tab control leads via manifest.json style routing to display a view in the tabs content area.
This is my current working code which is within the onBeforeRendering event of the view controller:
onBeforeRendering: function(oEvent){
var sPath = this.getView().getBindingContext("Projects").getPath(); // something like /task/6
console.log('Path='+sPath)
var oModel = this.getView().getModel("Projects");
var oTask = oModel.getProperty(sPath + "/brief");
if (oTask) { // looks like /brief exists so must already have loaded the brief
// nothing to do
console.log('Use existing data')
}
else { // /brief not yet present so we need to load it up
console.log('Load new data')
oModel.setProperty(sPath + "/brief", "This is the brief...") // replace with loaddata() from server, use attachRequestCompleted to call function to modify model.
}}
Question - is this the correct approach?
Edit: Based on discussion in this question I modified my code to use an event that fires per display of the view. onBeforeRendering turned out to run without much apparent predictability - which I am sure it has but in any case I wanted a one-per-display event. Also, I fleshed out the code further but retained the basic structure and it appears to do what I wanted.
This is a valid approach. But you should think aboute following use case: What happens if the data you loaded have been changed at the backend? The JSONModel does not give you any support here as it acts dumb data store only.

Waiting for sap.ui.table.Table rendered after bound model has changed

I have sap.ui.table.Table which rows are bound to an JSONModel.
var oListModel = new sap.ui.model.json.JSONModel();
//oTable created here (sap.ui.table.Table)
oTable.setModel(oListModel);
oTable.bindRows("/");
When the table is rendered, i.e. the DOM is created for this table, i need to reference to the DOM to pass the DOM elements (table rows) to a library which will make them draggable.
My problem is: How do i know when the DOM for the table is created after the model has been changed and the table is rerendered? I didnt find any listener. The view controller's listener onAfterRendering() didn't help me.
The model is filled with data after a XMLHTTPRequest is successful. When i set the model in the success handler of the xht request and try to access the DOM elments directly afterwards they don't exist yet.
Thank you for your help!
You can add an event delegate
var oMyTable = new sap.ui.table.Table();
oMyTable.addEventDelegate({
onAfterRendering: function() {
$table = this.getDomRef() ....
}
});
a better way is to extend the control see Using addDelegate to extend a control to use third party functionality
UPDATE
the example in that blog doesn't work anymore fixed here
I had a similar issue recently where i had to access an element after a smartform (where the element is present) rendered onto the view. I posted my query here as well as my final solution (based on the accepted answer of #Dopedev). I am using XML views - including nested XML views - here however and the onAfterRendering didn't help for me as well.
I guess you could look at this solution - like it's mentioned in the accepted answer, it may not be an optimal solution, but it sure works. In my case there is not much of a performance issue with the binding of the DOMNodeInserted since it is being called in the onAfterRendering of the nested view that consists of only the smartform with an immediate unbinding upon finding.
The condition if (id === "yourtableid") { } should be enough to identify and pass on. Since you have a table and thus several child nodes, unbinding is imperative at this point.
Mutation Observer is the preferred method but i guess you may need to check the browser compatibility table at the end of the page to see if it matches your requirements. There is an example here. I have used Mutation Observer (outside of a SAPUI5/openUI5 environment) earlier and found it very convenient(and performant) to listen to DOM insert events. In fact the sap.ui.dt package consists of MutationObserver.js

How to call get_entity method

I'm just starting with SAP FIORI app developing.
I created simple oData model for SAP user details, I implemented two methods:
get_entityset - receives list of users with personal number and full name
get_entity - receives more details of single user (by username).
When I call the service from browser all works fine. How do I call my get_entity method when loading detail page of Master-Detail FIORI app. I used Master-Detail template from WebIDE, but only get_entitset is called and detail screen uses only set data.
How should I define the data binding (in Detail controller I guess)?
Let's assume your Entity is called User and your EntitySet is called Users. We also assume your Entity has one key field of type Edm.String called UserId and another field called FullName of type Edm.String.
var sPath = "/the/path/to/my/service";
var oModel = new sap.ui.model.odata.ODataModel(sPath);
sap.ui.getCore().setModel(oModel);
var oText = new sap.ui.commons.TextView({
text: "{FullName}"
});
oText.bindElement("/Users('MyUserId')");
oText.placeAt("content");
Since you are binding to "/Products('MyProductId')" your "get_entity" is called. Binding to "/Products" would call "get_entityset". However, a binding to "/Products" is used for tables or lists and usually not for a simple TextView (like the above example). There are many tutorials on the web and you will see that this is not as complicated as you might guess.

SAPUI5 - navigation - Binding not working

Demo - http://jsbin.com/bukanagobu/1/edit
The problem is when i click on one of the item, it navigates to the next view but it is not displaying the firstname and lastname.
I have saved the model as 'data'.
Can anyone help me in finding the error ?
You have made two mistakes in your code:
When getting the binding context upon clicking an entry in the list, you must specify the named model name 'data':
var oBindingContext = evt.getSource().getBindingContext("data");
// if using named models, specify which model you want to use
Also, when setting the binding context to the detail view, you must also set the model name to 'data':
page2.setBindingContext(oBindingContext, "data");
// also, name the context model to 'data'
See the updated JSBin here : http://jsbin.com/fehoqu/1/edit?html,output