Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Dealing with updates. Is it possible not to touch min index? #229

Closed
priandsf opened this issue Aug 15, 2019 · 4 comments
Closed

Dealing with updates. Is it possible not to touch min index? #229

priandsf opened this issue Aug 15, 2019 · 4 comments

Comments

@priandsf
Copy link
Contributor

priandsf commented Aug 15, 2019

We have a data source that serves the data from an actual server implementing some sort of pagination. It means that we can access the data using an offset and count, which maps the ui-scroll data source requirements.
The problem arises with updates. Suppose that we want to delete the element №3. From the database standpoint, all the elements accessed with a 3+ index should now be accessed with that index minus one (the №4 now becomes №3)

From a ui-scroll standpoint, we do 2 things:

  • we call applyUpdate(3,[]) to get the element removed
  • we call applyUpdate( updater() ) to reload all the elements currently in the buffer, because what is at index n is now what was at index n+1, so the buffer does not hold the proper items

But this is not enough as buffer.first is not decremented when the removed element is < buffer.first. Thus, if we remove multiple rows, this can lead to a situation where buffer.first > number of elements, which confuses ui-scroll (it displays blank data)
Also, if we remove the first element, maxIndex stays the same while minIndex is incremented, which is obviously not what is desired in our use case.

We finally got it work, but I consider our solution 'fragile', as it can break if some implementation details change. What would be your advise to support our use case?

We can add new methods to the adapter like:

  • insertItems(index,n)
  • removeItems(index,n)
    These methods will update the buffer accordingly (first, maxIndex) and will update the items in the buffer by calling the datasource (or through an updater function?)
@dhilt
Copy link
Member

dhilt commented Aug 15, 2019

@priandsf I would split the discussion onto two parts: on items indexes shifting and on buffer borders shifting.

For the first point, I would say that the indexes part of the game should be played on the data side, outside the ui-scroll. And the issue becomes a matter of proper data structuring and proper data flowing. We have one pretty complex demo related to discussed situation, link. The remove method on the frontend does almost nothing but return [] for a given index via adapter.applyUpdates, link. But first, it removes appropriate item on the backend, and there the magic happens. The server is responsible for shifting the items indexes, link. And no reload is needed with such approach. In the demo the backend mock implementation is really not performant, but it should work as a proof of concept.

For the second point, yes, currently we are limited by how the ui-scroll is implemented. When you remove an item via adapter, the ui-scroll might decrement its max index or increment its min index (in case you are removing the topmost item), link. If you want another behaviour on, say, removing the topmost item, let's discuss what could be suggested in that case. Maybe decrement Buffer's max index too?

In addition, you mentioned server-side pagination, I'd like you to look at this sample which can be useful. It shows how we can implement a layer connecting index-count API of the ui-scroll and pages API of the external datasource.

@priandsf
Copy link
Contributor Author

Thanks for your reply @dhilt , as ever!

I agree that these are 2 different points, although they are somewhat related. Both deal with a datasource which is a mutable array of data, with a fixed first index (generally #0). I believe that this is quite a common use case when displaying data coming from a server.

1- I looked at the sample you mentioned and it makes sense, although the use case is a bit different: in the example case, an index is assigned to every single element and it is immutable. In our case, the element index depends on the position in the dataset, and can vary when elements are inserted or removed. Having an immutable index implies maintaining a map between the elements and the indexes, which is a bit complex.
When elements are inserted/removed, all what we know is the number of items added or removed, as well as the index where it happened (ex: deleted 5 items at position 16).
So far, the solution exposed in my first post works so is not a big deal for us right now. But I'm still thinking of a better solution.

2- For the second issue, updating maxIndex doesn't seem to be enough, as Padding also updates the element indexes for non top elements.
We came with a solution we added an optional extra parameter to adapter.applyUpdate()1. It indicates how it should deal with the top elements. If we pass true`, then top elements are processed as any other elements.
Do you think of a better solution? I don't know if you're interested by ours, just let me know.

@dhilt
Copy link
Member

dhilt commented Aug 16, 2019

@priandsf May I ask you to try immutable-top branch? It provides immutableTop option for Adapter.applyUpdates calls, the detailed information is in Pull Request #230.

@dhilt dhilt changed the title Dealing with updates Dealing with updates. Is it possible not to touch min index? Aug 17, 2019
@dhilt
Copy link
Member

dhilt commented Aug 17, 2019

v1.7.6 had been released, I also added options argument to Adapter.prepend method.

@dhilt dhilt closed this as completed Aug 17, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants