Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

OData V4 Changes Are Not Reflected in Other Bindings

Tags:

odata

sapui5

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?

like image 298
Flo Avatar asked Mar 14 '18 10:03

Flo


1 Answers

See https://embed.plnkr.co/qatUyq/?show=preview:%3Fsap-ui-xx-componentPreload%3Doff

https://embed.plnkr.co/qatUyq/ Minimal example using the OData V4 TripPin service

Keep in mind that v4.ODataModel is still work in progress. 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 [...].

Update: According to the UI5 roadmap (SAP Community account required), the data binding synchronization support is "planned for Q2 2021".

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 the context binding (detail page).
  2. After user presses Submit, call refresh("myGroupId") from the 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" (Unless sharedRequests is enabled) - 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 to the backend 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 after all the related controls are rerendered.
    • 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 model 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. [doc]

  5. Models usually support events such as requestSent and requestCompleted. Why can't I make use of them in v4.ODataModel?

    • It's just not supported by design. See Unsupported Superclass Methods and Events.

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

like image 158
Boghyon Hoffmann Avatar answered Sep 18 '22 10:09

Boghyon Hoffmann