Openui5: Factory function for JSON model requires rebuild every single update

Created on 8 Aug 2016  路  7Comments  路  Source: SAP/openui5

Dear developers,

Here is a very serious issue we detected in SAPUI5.

The business requirement:
A view contains chat history. Every new message should be shown immediately.

The problem:
With each new message the app works slower and slower

The code:
We catch message from websocket and update the JSON model with the code like this:

var aMessages = oMessagesModel.getProperty(sPath);
...
aMessages.push(oData);
oMessagesModel.refresh();

As this model is bound to the view it forces the update of the corresponding list.

We use factory function to insert diffrerent content in one list.

However in ManagedObject.updateAggregation method we have an insane line that is destroying all items and recreating them again.

// If a factory function is used, aggregation must be completely rebuild
if (!oBindingInfo.template) {
thisoAggregationInfo._sDestructor;
}

The program's behavior becomes completely unacceptable.

What we need is just insert a new item into the list.

Why should we rerender all the control?

Could you please find a workaround how to avoid the whole list destruction and provide an opportunity just to update it with new lines.

Thanks!

Petr Plenkov.

consulting

Most helpful comment

Dear Michael,

This issue was not about the list behavoir in common.

It was about using factory function.

When it's implemented the items are not just being rerendered, they are being newly created every single update.

That was the issue.

Treshhold property won't help to avoid this case as it's described in ManagedObject therefore applied to all inherited objects.'

Could you somehow provide an option to deactivate manually this rebuild?

Thanks!

Petr.

All 7 comments

chrome_2016-08-08_16-36-16

Which control is used in your view to show the chat history? I could imagine a "growing enabled" control like sap.m.Table could handle this better, as it does not run the code in ManagedObject that is troublesome for you. But I am not an expert for sap.m.Table...

I use list. In fact it's inherited from sap.m.List control now.

What I did to solve the issue - I deactivated items deletion while update. Also I remembered items for later rendering after update is finished.

sap.ui.define([
                               "sap/m/List"
                ],
                function(Control) {
                               "use strict";

                               return Control.extend("fiori.plugin.chat.control.MessageList", {

                                               renderer: "sap.m.ListRenderer",

                                               updateItems: function() {

                                                               var fnDestroyItems = this.destroyItems;

                                                               this.destroyItems = function() {};

                                                               var oResult = Control.prototype.updateItems.apply(this, arguments);

                                                               this.destroyItems = fnDestroyItems;

                                                               return oResult;

                                               },

                                               addItem: function(oItem) {

                                                               var oThis = Control.prototype.addItem.apply(this, arguments);

                                                               if (!oThis.itemsToRender) {
                                                                              oThis.itemsToRender = [];
                                                               }

                                                               oThis.itemsToRender.push(oItem);

                                                               return oThis;

                                               }

                               });
                }
);

Hello ThePlenkov,

what you describe above is the current default behavior of the list and table controls in the sap.m namepsace. They rerender all items when you add or remove an item in the "items" aggregation.

To overcome the issue you experience, you can turn on the "growing" property and set a meaningful "growingThreshold" (in case you don't want growing set it to a very high number) and then only the altered items in the aggregation will be rerendered. The growing mode enables a different update behavior of the content.

Hope that helps,

Michael

Dear Michael,

This issue was not about the list behavoir in common.

It was about using factory function.

When it's implemented the items are not just being rerendered, they are being newly created every single update.

That was the issue.

Treshhold property won't help to avoid this case as it's described in ManagedObject therefore applied to all inherited objects.'

Could you somehow provide an option to deactivate manually this rebuild?

Thanks!

Petr.

I ran into the same problem. I am using a factory function to create a list of items in a customer-provided Accordion control. Now I wanted to implement endless scrolling, by adding new items to the end of the list (using aggregation binding). However, as soon as I new items are added, the whole control re-renders, which is pretty useless for endless scrolling.

@ThePlenkov Did you ever find a solution to this?

@derwaldgeist hi, actually growing list feature did help a lot.

Was this page helpful?
0 / 5 - 0 ratings