OData V4 Changes Are Not Reflected in Other Bindin

2019-04-20 05:35发布

I created a UI5 master-detail page:

Master

<List items="{som>/Users}">
  <StandardListItem
    type="Navigation"
    press="onItemPress"
    title="{som>UserName}"
  />
</List>
onItemPress: function(oEvent) {
  var oUserContext = oEvent.getSource().getBindingContext("som");
  var oUser = oUserContext.getObject();
  this.getRouter().navTo("userDetails", {userId: oUser.Id});
}

Detail

onInit: function () {
  var route = this.getRouter().getRoute("userDetails");
  route.attachPatternMatched(this._onObjectMatched, this);
},

_onObjectMatched: function (oEvent) {
  var sUserId = oEvent.getParameter("arguments").userId;
  this.getView().bindElement({
    path: "som>/Users('"+sUserId+"')",
    model: "som"
  });
},

reload: function() {
  this.getView().getModel("som").refresh();
},
<fLayout:SimpleForm id="userForm">
  <Button text="reload" press="reload"/>
  <Label text="{i18n>settings.user.id}"/>
  <Input editable="false" value="{som>Id}"/>
  <Label text="{i18n>settings.user.username}"/>
  <Input value="{som>UserName}"/>
  <Label text="{i18n>settings.user.email}"/>
  <Input value="{som>Email}"/>
  <Label text="{i18n>settings.user.firstname}"/>
  <Input value="{som>FirstName}"/>
  <Label text="{i18n>settings.user.lastname}"/>
  <Input value="{som>LastName}"/>
</fLayout:SimpleForm>

Everything is working fine. But when I change a user in the detail view, it is being updated but not in the master view! With the reload method, I can manually refresh it. But how can I fire this automatically after a change? Can I bind a change event on the SimpleForm?

标签: odata sapui5
2条回答
来,给爷笑一个
2楼-- · 2019-04-20 05:53

V4 model works with promise.

When submit the changes you can use .then(), so you can refresh the model.

...
            var oView = this.getView();

            function refreshModel() {
                oView.getModel().refresh();
            }

            oView.getModel().submitBatch(sGroupId).then(refreshModel);
...

https://sapui5.hana.ondemand.com/#/api/sap.ui.model.odata.v4.ODataModel/methods/submitBatch

查看更多
冷血范
3楼-- · 2019-04-20 06:10

Here is a working example: https://embed.plnkr.co/qatUyq/?show=preview

https://embed.plnkr.co/qatUyq/

We need to keep in mind that v4.ODataModel is still work in progress. E.g. the synchronization mode has to be "None" currently.

synchronizationMode
Controls synchronization between different bindings which refer to the same data for the case data changes in one binding. Must be set to 'None' which means bindings are not synchronized at all [...].

Therefore, the application itself has to identify related bindings and refresh them manually. To make it efficient, we can send such GET requests together with the update request via batch group ID which is what v2.ODataModel automatically does (unless refreshAfterChange is disabled).

In the example above, I used the following settings and APIs:

  1. $$updateGroupId: "myGroupId" for context binding (detail page)
  2. After user clicks on Submit, refresh("myGroupId") from list binding (master list)
  3. And finally submitBatch("myGroupId").

If we then inspect the request payload, we can see that the PATCH and GET requests are bundled together. Hence, the master list is refreshed at the same time.


Q&A

  1. What is the default binding mode in v4.ODataModel?

    • It's "TwoWay" - The UI changes the model data and the other way around. When the change is not stored in a batch queue, the corresponding request is sent immediately.
  2. How do I know if I'm using batch mode or not?

    • Pretty much all bindings in v4, as well as the model itself, support the parameter $$groupId for read, and certain bindings support $$updateGroupId for update requests.
      • If the ID is set to "$direct", the corresponding requests are sent directly without batch. Those requests are easier to diagnose and cacheable by the browser.
      • If the ID is a custom string (like in the example above), the corresponding requests are to be sent explicitly by the API submitBatch.
      • If there is no such ID defined, the default value is set to "$auto", meaning by default, requests are sent as batch automatically when the corresponding control gets (re)rendered.
    • Take a look at the documentation topic Batch Control
  3. How can the application make sure that refreshing the list is always applied after the update is done even though those two requests (GET & PATCH) are bundled as one?
    • The ODataModel already takes care of this:

      The OData V4 model automatically puts all non-GET requests into a single change set, which is located at the beginning of a batch request. All GET requests are put after it.

  4. Why can I call submitBatch without adding the groups to "deferred groups" beforehand like I did with v2.ODataModel?
    • V4 has simplified dealing with batch groups:

      Application groups are by default deferred; there is no need to set or get deferred groups. You just need the submitBatch method on the model to control execution of the batch. [src]

  5. Model supports events such as requestSent and requestCompleted. Why can't I make use of them in v4.ODataModel?
    • It's not supported by design:

      [...] attaching an event handler leads to an error.

Hope I made some things more clear. The latest documentation about OData V4 in UI5 can be found in: https://openui5nightly.hana.ondemand.com/#/topic/5de13cf4dd1f4a3480f7e2eaaee3f5b8

查看更多
登录 后发表回答