6

I have a master-detail application that consumes an OData service (declared in manifest.json).

In the detail controller, I bind the model to the view in the following way (this method is attached to a router object).

_onObjectMatched: function(oEvent) {
    this.getView().bindElement({
        path: "/ContractCompSet('" + oEvent.getParameter("arguments").id + "')",
        model: "contracts"
    });
}

How can I access the actual bound model object from within this controller?

Closest I got (but seems too be a little too complicated) is as follows

var path = this.getView().getElementBinding('contracts').sPath.substring(1);
var model = this.getView().getModel('contracts').oData[path];
Marc
  • 6,051
  • 5
  • 26
  • 56
  • Hi Marc, it's been some time since you posted it but I have the same question: I would like to have access to the single data in the Detail Controller and so far I can only make use of the data in the view itself. Did you solve above problem? – Skye Mar 07 '18 at 07:50
  • Yes, you can access all data of your view in your controller. I usually do `this.getView().getBindingContext("NAME_OF_MODEL")`. This gives me the context which is bound to the view. You can then do `.getObject()` to access the actual data. Give me a code example and I can try to help. – Marc Mar 15 '18 at 17:07

2 Answers2

6

Well your approach isn't to far off and is indeed pretty much the same as hirses.

The point is the binding does not contain "just" the bound model object. It contains the information about model, path to the "bound object" and context. These can be retrieved from the binding. To access the "bound object" you then have basically two paths available.

Get the model and path from the binding and access the "bound object" via the model: (this is what you and hirse outlined)

var path = this.getView().getElementBinding('contracts').sPath;
var boundObject = this.getView().getModel('contracts').getProperty(path);

Or get the context and path and access the "bound object" that way:

var context = this.getView().getElementBinding('contracts').oContext;
var boundObject = context.getProperty(context.getPath());

Without having done to much research into this I would prefer the second option. It just seems more along the line of how the context binding is intended.

Carsten
  • 1,511
  • 2
  • 13
  • 24
  • When is this method available (from a chronological pov)? If I call this right after `bindElement()`, `oContext` is `undefined`. Is there some kind of Event `onBindingReady`? (My current solution also doesn't work if I try to access the model right after binding it) – Marc Aug 20 '15 at 13:24
  • Not to sure on this since I never had that issue. But if you use a server side model and the object has not yet been loaded a request is sent to retrieve it. Since this might be a asynchronous request it might take a time complete. This might be why the data is not available immediatly. You might want to have a look at the network activity. The dataReceived' event of this sap.ui.model.Binding might also be a good starting point to look into for an event to hook into it to. https://sapui5.netweaver.ondemand.com/sdk/docs/api/symbols/sap.ui.model.Binding.html#attachDataReceived – Carsten Aug 20 '15 at 13:46
  • I may have found something slightly better: When calling `bindElement` I add a function for the change event (`events: { change: function() { } }` where I can access the model via `this.getModel().getProperty(this.getPath())`. But tbh I am not really sure what exactly `this` is :D Thx for your great help anyway. – Marc Aug 20 '15 at 13:59
  • 'this' is the calling source of the event. – Carsten Aug 20 '15 at 14:25
  • Model binding is asynchronous, so when you try to retrieve the `oContext` you get `undefined` because it may not be available yet in that time. For example, if you bind something to the view, like this: `this.getView().bindElement(sEntityPath);` then for a proper retrieving of your new context, you should try to get it in a callback to the **ModelContextChanged** event `this.getView().attachModelContextChange(function(){ /* your operations */});` – FreeFend Apr 03 '18 at 12:26
2

I would have thought,

this.getView().getModel('contracts')

gives you the Model Object (as in an object of type sap.ui.model.Model or subclass).

If you are referring to the data in the Model, you can use the following:

this.getView().getModel('contracts').getProperty("/")
hirse
  • 2,394
  • 1
  • 22
  • 24
  • This yields the same as `this.getView().getModel('contracts').oData`, an object that contains every fetched modelobject (`ContractCompSet('1'), ContractCompSet('2')` etc). I would have preferred the single object that is bound to the view though. – Marc Aug 20 '15 at 11:46