Reputation: 1676
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?
Upvotes: 2
Views: 2968
Reputation: 18064
Use .concat
api 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.
Upvotes: 2
Reputation: 4920
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);
Upvotes: 1