Matti says...

This is my Vaadin related blog. Ideas and opinions presented here should not be taken as official statements from Vaadin Ltd. I'll be adding some stuff here that I don't want to get lost in the forum, but which doesn't fit into our official blog. Followups to Vaadin forum please!

Back

More on lazy data binding

I recently published some great helpers for connecting large amount of data to UI components. They provide you simple tools to make a well performing databinding with Vaadin UI components and a service layer implemented with e.g. Spring Data or a stateless EJB.

Since the first “release” I have played a bit more with them, not least due to the XRebel introduction we held with Simon Maple from ZeroTurnaround a week ago. I still like the concept a lot and wanted to make some improvements to it. Now that I’m bit sick and at the home office, it was a nice opportunity for some additional improvements and a new release. Solutions introduced below are available since the Viritin version 1.26.

Filtering, SOLVED

Filtering is most often needed when you want to have a select component at the UI that users can filter efficiently with some text input. ComboBox is the Vaadin component of choice for this, but as you might know, making a really well performing data binding for it may be a bit tricky.

The solution in Viritin is now called LazyComboBox. It uses customized version of the LazyList and, in addition to “paging”, you can use it to delegate sorting to your backend as well. You can find a usage example from my jpa-invoicer example. It is bit hairy as it also contains support for adding new items and it filters values from another select visible in the UI as well, but you should get a basic idea from these lines.

Sorting, SOLVED

Sorting is another thing that is in Vaadin delegated to its Container interface. I’m not quite sure if I’m a big fan of that decision, but now you can overcome this using MTable. The initial version actually allowed sorting for LazyList backed UI components, even though that is something very stupid thing to do and was most probably broken in many multiple ways. If you are using the simple LazyList, sorting is now correctly disabled by default for all properties.

But that don’t excactly help if your requirements says you need sorting :-) You can now implement a totally customized sorting logic by using SortListener, that you can use to bypass the default “container sorting” done by Vaadin. You can also explicitly define the properties the UI should allow sorting on using setSortableProperties method.

However, instead of the above customization, I’d suggest to look at SortableLazyList, or the related constructors in MTable. This LazyList extension, supported natively by the MTable, also passes information about sort direction and property to your “backend binding”. With Java 8 lambdas, the well performing sortable and pageable data binding now looks like this:

table.setBeans(new SortableLazyList<>(
        // entity fetching strategy
        (firstRow, asc, sortProperty) -> repo.findAll(
                new PageRequest(
                        firstRow / PAGESIZE, 
                        PAGESIZE,
                        asc ? Sort.Direction.ASC : Sort.Direction.DESC,
                        // fall back to id as "natural order"
                        sortProperty == null ? "id" : sortProperty
                )
        ).getContent(),
        // count fetching strategy
        () -> (int) repo.count(),
        PAGESIZE
));
 

The above example is taken from a Spring Data Vaadin CRUD example and only uses the default methods generously provided by the Spring Data JpaRepository. BTW. If you don’t know about Spring Data, and even if not needing a well performing sortable lazy binding to your data today, check it out and play with the example. In case you didn’t know it, Spring Data is a super cool beast, sincerely. I miss it every time I work on a Java EE project. And naturally, it works perfectly with Vaadin ;-)

Improvement ideas, WELCOME

Check out the latest version of Viritin from the Directory and let me know what you think! If you have improvement ideas, feel free to post the to the github project, issues and pull requests are both more than welcome.

 
Comments
Trackback URL:

Add Comment
Hi Matti!
Just started using the Viritin add-on for lazy loading large datasets into Grid.
The Grid needs to be filtered by inline header-row filtering.
Since the MGrid ListContainer is not implementing the Filerable interface, what would be the best practice for filtering the datasets?
In the Viritin Wiki in github it is stated that:
"If your UI has a filtering for the listing, you can simply use the filtering data directly in your binding code. To notify the components of changed data, also call refreshRows() method, that will clear the cache in components."
Could you please elaborate on that or maybe provide an example?
Thank you in advance.
Posted on 4/19/16 1:33 PM.
Hi Matti,

I want to use MultiSelect / MultiSort / InHeader Filtering Table or Grid. How should I go about it?
Posted on 1/25/17 12:54 PM.