Getting the bound data object of pressed table row - getBindingContext() returns undefeind

Mathias Conradt picture Mathias Conradt · Jul 22, 2014 · Viewed 21k times · Source

In SAP UI5, I try to get the data object (in my controller) that is bound to a table row when the user presses it. My view is defined in XML, and my controller is in JS of course.

I have checked How to get content of a row in sap.m.table already but it doesn't work for me, or something is missing.

My view (the relevant part):

<Panel>
  <Table id="lineItemList" items="{
    path: 'statusJobs>/jobs',
    sorter: {
      path: 'start',
      descending: true
    }
  }">
  <headerToolbar>
    <!-- ... -->
  </headerToolbar>
  <columns>
    <Column hAlign="Left" vAlign="Middle">
      <Label text="Job" />
    </Column>
    <Column hAlign="Center" vAlign="Middle">
      <Label text="Start" />
    </Column>
    <Column hAlign="Center" vAlign="Middle">
      <Label text="End" />
    </Column>
    <Column hAlign="Right" vAlign="Middle">
      <Label text="Success" />
    </Column>
  </columns>
  <ColumnListItem
    type="Navigation"
    press=".handleLineItemPress"
  >
    <Text text="{statusJobs>job}" />
    <Text text="{
      path: 'statusJobs>start',
      formatter:'util.Formatter.Date'}"
    />
    <Text text="{
      path: 'statusJobs>end',
      formatter: 'util.Formatter.Date'}"
    />
    <Text text="{statusJobs>status}"/>
  </ColumnListItem>
</Table>     

The relevant part here is obviously:

<ColumnListItem
  type="Navigation"
  press=".handleLineItemPress"
>

And in my controller, I have this:

handleLineItemPress: function(evt) {
  console.log('evt.getSource: ' + evt.getSource());
  console.log('evt.getBindingContext: ' + evt.getSource().getBindingContext());
}

which logs as follows:

evt.getSource: Element sap.m.ColumnListItem#__item11-StatusJobs--lineItemList-0 evt.getBindingContext: undefined

evt.getSource returns the ColumnListItem, so of course from there, I could use the object hierarchy and fetch the text of a cell, like:

evt.getSource().getCells()[0].getText();

But this does not seem to be the right way and especially does not give the the entire object nor its unique ID, which I happen to not display in the table.

I am somehow missing the connection back to my data model, that I had bound earlier in the code, in the <Table> item, as follows:

items="{
  path: 'statusJobs>/jobs',
  sorter: {
    path: 'start',
    descending: true
  }
}"

Answer

Qualiture picture Qualiture · Jul 22, 2014

I hate to say it, but I have had the same issue, and it took me quite some time to find the cause...

It's all related to the use of named models, in your case statusJobs.

If you want to retrieve the binding context for items bound to a named attribute, for some reason (honestly, I can't think of any) you also have to specify the named model:

evt.getSource().getBindingContext("statusJobs");

will return the correct binding context.

Thus, to retrieve the actual object bound to the pressed line item, you could then use:

var obj = evt.getSource().getBindingContext("statusJobs").getObject();

Since a context can't be bound to more than one model (to my knowledge) I really don't understand why you need to specifically give the named model name as a parameter, but for now I guess we have to live with this behavior