2

I need to enable or disable a button based on the bound array size.

<mvc:View
  xmlns="sap.m"
  xmlns:mvc="sap.ui.core.mvc"
  xmlns:core="sap.ui.core"
  height="100%"
  controllerName="test.controller.expbind">
  <Button text="Need to Enable" enabled="{= ${/listOfData}.length > 0 }"/>
  <List headerText="Data" items="{/listOfData}">
    <StandardListItem title="{Name}" />
  </List>
  <Button text="AddSomeData" press=".onPress" />
</mvc:View>
onInit: function() {
  this.viewModel = new JSONModel({
    listOfData: []
  });
  this.getView().setModel(this.viewModel);
},

onPress: function() {
  var existingdata = this.viewModel.getProperty('/listOfData');
  existingdata.push({ Name:"New" });
  this.viewModel.setProperty('/listOfData', existingdata);
},

After adding the data, the "Need to Enable"-button has to be enabled, but its not happening.

Is there ayny issue with my expression binding?

Boghyon Hoffmann
  • 17,103
  • 12
  • 72
  • 170
chiranjeevigk
  • 1,636
  • 1
  • 23
  • 43
  • Does this answer your question? [Add a New Item to a Table / List](https://stackoverflow.com/questions/48222553/add-a-new-item-to-a-table-list) – Boghyon Hoffmann Jul 12 '22 at 20:01

2 Answers2

2

Use .concatapi instead.

const myArray = myClientModel.getProperty('/data');
// instead of myArray.push({/*...*/});
const myNewArray = myArray.concat({/*...*/}); // myNewArray !== myArray
myClientModel.setProperty('/data', /*instead of the old reference:*/myNewArray);

.push should be avoided since it manipulates the original array causing side-effects. The real reason why it didn't work in your case, however, was because the reference passed to setProperty was identical to the old reference (internally compared with === within deepEqual()). Hence, UI5 sees no change and doesn't notify any listeners.

model.refresh(true) unnecessarily forces all bindings (incl. aggregation bindings) and all listeners to re-calculate everything.

.concat on the other hand, creates a new reference. UI5 notifies then only those listeners that care about the change.

Boghyon Hoffmann
  • 17,103
  • 12
  • 72
  • 170
1

Since XMLView expression binding is calculated during pre-processing, it's not being recalculated upon updating the model directly.

You can avoid this behavior by using a formatter function, or update the model with a forced refresh of the bindings after you have updated your model:

this.viewModel.refresh(true);
Qualiture
  • 4,900
  • 7
  • 27
  • 38