При обновлении модели в ui5 привязка выражений не работает
Мне нужно включить или отключить кнопку в зависимости от длины данных, так что вот мое представление XML
<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="{
path: '/listOfData'
}" >
<StandardListItem title="{Name}"/>
</List>
<Button text="AddSomeData" press="onPress" />
</mvc:View>
И в методе контроллера init будет инициализировать модель и onPress я добавляю некоторые данные в модель
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);
}
После добавления данных должна быть включена кнопка " Необходимо включить", но этого не происходит
Любая проблема - это привязка или выражение?
1 ответ
Поскольку привязка выражения XMLView вычисляется во время предварительной обработки, она не пересчитывается при непосредственном обновлении модели.
Вы можете избежать этого, используя функцию форматирования, или обновить модель принудительным обновлением привязок после обновления вашей модели:
this.viewModel.refresh(true);
Использовать .concat
api вместо этого.
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
следует избегать, поскольку он манипулирует исходным массивом, вызывая побочные эффекты. Однако настоящая причина, по которой это не сработало в вашем случае, заключалась в том, что ссылка была передана на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.