1

I have a problem with data in a <p:rowExpansion> being loaded before the row is expanded (which leads to loads of web service requests).

I am using PrimeFaces 5.2. I have a dataTable with lazy loading and pagination. Inside of the table, I have <p:rowToggler> with a <p:rowExpansion>:

<p:dataTable var="order"
             widgetVar="orderTable"
             lazy="true"
             value="#{ordersBean.orders}"
             paginator="true"
             rows="20"
             rowsPerPageTemplate="20,50,100"
             filterDelay="300"
             styleClass="filtered">

    <p:column width="4%">
        <p:rowToggler />
    </p:column>

    <p:column headerText="Order number" width="96%">
        <h:outputText value="#{order.number}" />
    </p:column>

    <p:rowExpansion>
        <h:panelGrid columns="1">
            <h:outputText value="#{order.number}" />
            <h:outputText value="#{order.info}" />

            <h:dataTable var="item" value="#{ordersBean.getItemsInOrder(order.number)}">
                <h:column>
                    <h:outputText value=" #{item.title}" />
                </h:column>
            </h:dataTable>

        </h:panelGrid>
    </p:rowExpansion>
</p:dataTable>

When I first load the page, the getItemsInOrder() method is not called, except for when I expand a row. But if I navigate to page 2 (or if I navigate back to page 1 later) using the paginator, then getItemsInOrder() is called for every row in the outer table. Since I have 20 rows showing, navigating between the pages leads to 20 web service requests (in getItemsInOrder()).

How do I prevent it from calling the getItemsInOrder() method until the row is expanded?

Tiny
  • 27,221
  • 105
  • 339
  • 599
user208370
  • 35
  • 5
  • No idea... can you create an mcve so it is easier to reproduce? And maybe [this issue](https://github.com/primefaces/primefaces/issues/43) is related somehow – Kukeltje Aug 11 '15 at 14:04
  • I've created an mcve: https://github.com/mcerik/rowexpansion from the example code above. getItemsInOrder gets called three times every time I change page with the paginator. The problem is not how many times it is called but why is it called at all before the row is expanded? – user208370 Aug 12 '15 at 06:17
  • Nice mcve, why not just post it in here instead of your original code? And are you sure it does not trhow errors? I seeca `lazy="true"` without actually using a lazydatamodel – Kukeltje Aug 12 '15 at 06:39
  • The code snipped in here should be identical to what's in the mcve. I copied it from here. It does not throw any errors. `lazy="true"` is used in the real project, I forgot to remove it here. – user208370 Aug 12 '15 at 06:46
  • I don't see a bean in here ;-) . So the datatatable being lazy or not does not make a difference? – Kukeltje Aug 12 '15 at 06:54
  • No, no difference. Maybe my understanding of when the data is supposed to be loaded for the `p:rowExpansion` is wrong, but I think the behaviour is strange since no data is loaded for the expansions for the initial page request. – user208370 Aug 12 '15 at 07:01
  • I agree. Behaviour looks indeed strange. I'll try this afternoon during lunchbreak. Have you tried dumping just the arraylist in a colum instead of using an `h:datatable` ? – Kukeltje Aug 12 '15 at 07:03
  • Btw is it called 3 times when you navigate? You have 20rows of orders and each row has 5 items. In your initial post you said it was called 20 times and now only 3? It being called more than once is not strange. It is supposed to be a getter. See http://stackoverflow.com/questions/22940966/datatable-rowexpansion-lazy-load. If called multiple times with the same value, make sure in the bean that holds your method, you cache consecutive requests for the same value – Kukeltje Aug 12 '15 at 07:50
  • Sorry, I mean that `getItemsInOrder` is called three times **for every row** (order), times 20 rows. If I add more properties (which I am in the real case) then the method gets called even more times, but that is expected and I will prevent the web service from being called with caching, just like you said. I changed to using `ui:repeat` to show the list of items but it makes no difference - the method is still called when changing pages with the paginator. – user208370 Aug 12 '15 at 08:34
  • @Kukeltje have you by any chance had any time to look into this? – user208370 Sep 09 '15 at 08:22

1 Answers1

1

I have the same problem. Until I find a better solution, this is the workaround I am using:

  • register a (DataTable event-) listener on event rowToggle.
  • In the listener, store an identifier of the toggled row. Hint: you can get the row object with event.getData()
  • Instead of directly accessing the data requesting component, write a proxy method in front of it which checks if the requested object belongs to the identifier stored in the listener.