0
votes

I have an OData model which I successfully use to fill eg. a table in a SAPUI5 app:

<Table items="{globalSettings>/APP_GLOBAL_PREFERENCES/}">

etc.

The entity set APP_GLOBAL_PREFERENCES consists of entities each having a KEY and VALUE property, with KEY being the, well, key.

Now, I'm trying to bind the textproperty of a <Text>control to a property of a specfic instance of the entity:

<Text text="The base URL is '{globalSettings>/APP_GLOBAL_PREFERENCES('BASE_URL')/VALUE}'" />

In order for this to work, I have to create an element binding, as suggested here. In my case, I do it in the lifecycle method onBeforeRendering of the associated controller:

onBeforeRendering: function () {
  this.getView().bindElement({
    path: '/APP_GLOBAL_PREFERENCES',
    model: 'globalSettings'
  });
}

I don't understand why this step is necessary, and I would like to avoid it. Can anyone explain why this step is required, or does anybody have a clue how to get by without it?

1

1 Answers

0
votes

In UI5, there are 3 types of bindings:

  • Aggregation bindings can be used with aggregation (for example table or list items). This requires an array of objects from data point of view. In this case, you have to configure a so-called template, which will be repeated for every instance of the aggregation. Here, you need to use relative binding, so you don't have include the array reference itself in the binding path.

  • Element bindings are used to bind objects from the model to a control (views are also controls!). If the control has any child elements, these child elements can be bound to any property of this object using relative binding.**

  • Property bindings are the elementary parts of a binding procedure; each control has more or less properties, and you can assign model values to these properties using property binding.

** This means, that in your Text control you have to use a relative binding, so just use {VALUE}. However, make sure that if APP_GLOBAL_PREFERENCES in your model points to an array, you have to select a specific item in your bindElement (for example:

this.getView().bindElement({ path: '/APP_GLOBAL_PREFERENCES('BASE_URL')', model: 'globalSettings' });).

Edit: Ok, now I see your problem! Answering your question: it's not necessary.

If you use the this.getView().bindElement(..) property, you can use relative path in your text control (assuming that you include the selection of the proper item in this segment). My examples are based on JSONModel:

this.getView().bindElement({ path: '/APP_GLOBAL_PREFERENCES/0', model: 'globalSettings' });

Then you can do this in your view: <Text text="{globalSettings>text}" />

If you skip the bindElement (but you've assigned the model to the view), you need to use the following path: <Text text="{globalSettings>/APP_GLOBAL_PREFERENCES/0/text}" />

If you are implementing a detail view, which gets the ID of the selected item as an URL parameter, it's recommended to use the bindElement with the selection to the given parameter; then in your XML view, you can use relative binding and you don't have to care about the ID of the item.