Search code examples
data-bindingodatasapui5

How to update ContextBinding (Element Binding) automatically after the size of its child ListBinding (Aggregation Binding) has changed?


Note: In order to demonstrate the below issue, I've created an example in Plunker. In there, I'm using a mock server due to the flaw of the writable service from odata.org. Nevertheless, the issue is reproducible with a real server as well.


Currently, I'm binding a child collection to a list relative to an expanded single entity through a navigation property. Something like this:

<Page title="Products"
  binding="{
    path: 'odataModel>/BusinessPartnerSet(\'0100000000\')',
    parameters: {
      expand: 'ToProducts'
    }
  }"
>
  <List items="{odataModel>ToProducts}">
    <StandardListItem title="{odataModel>ProductName}" />
  </List>
</Page>

Now, if I delete an item from the list, the ListBinding sends a batch request containing DELETE and GET. Here is a screenshot of the batchRequestSent event:

ListBinding Batch request when DELETE

The deleted item is gone from the ListBinding and the list is updated as expected. If I have an additional list with the same bindings, then that additional list gets also updated because of the TwoWay data binding (like the Plunker example above). So far so good.

Problem

But the problem is: The parent ContextBinding (in this case, the element binding of the Page) is not updated. This can be seen if you call bindingContext.getProperty("ToProducts") and it will return a list of binding paths in which the ones of the already deleted items are still there. I guess this is because there was no GET request sent from the ContextBinding but from the ListBinding only.

My question

If the change took place in the child ListBinding (either through DELETE or CREATE), how can the parent ContextBinding get notified about the change and update itself without sending an additional request, so that bindingContext.getProperty("ToProducts").length returns always the correct length?

Or differently, when the change occurs, how can I prevent UI5 from sending a GET request from the child ListBinding and let it send the request from the parent ContextBinding instead, so that the change gets propagated to the child ListBinding afterwards automatically?

Is there any standard approach to solve this kind of problem in UI5?


PS: The same problem does not apply to JSON-based bindings. It seems to be OData only.


Solution

  • If someone encounters the same issue: it turned out to be a bug in UI5 which is fixed in 1.46.7+.

    [FIX] ODataListBinding: Update expanded list array

    If the fix is not available in your current release, one workaround would be to refresh the parent binding by calling parentControl.getElementBinding("modelName").refresh(false, "yourDeferredGroupId") so that the GET request can be sent together with the DELETE request in a single batch request.

    Additionally, we can turn off refreshAfterChange (as krisho suggested) so that UI5 doesn't append yet other GET requests for corresponding ListBindings (relatively bound as well as absolutely bound ones). A disadvantage of this approach is that the absolutely bound ListBinding (which has the same content as the relatively bound one) has to be refreshed manually as well - if there is any.