0

I do have an JEE application with JSF. As soon as I do use the c:forEach element, then the backend call for detecting the items is called with each p:remoteCommand, talking to the backend, even if no update is done at all.

I do not have any idea why this is done! Can anybody help me with a solution or a workaround?

In Detail, I use Wildfly (e. g. version 26.0.1, but also seen with e. g. version 28) and PrimeFaces (version 11, also seen with other versions).
Switching from c:forEach to e. g. ui:repeat is not so simple, because in my real world usage I call an ui:include for each of the iterating elements for getting a very flexible UI. So far, this did only work with c:forEach.

But let's take a closer look to a minimal code example:

If I do have an XHTML page like:

<?xml version='1.0' encoding='UTF-8' ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
    xmlns:h="http://java.sun.com/jsf/html"
    xmlns:f="http://java.sun.com/jsf/core"
    xmlns:ui="http://java.sun.com/jsf/facelets"
    xmlns:p="http://primefaces.org/ui"
    xmlns:c="http://java.sun.com/jsp/jstl/core">

    <h:head>
        <title>Playground: c:forEach and p:remoteCommand</title>
    </h:head>

    <p:remoteCommand name="doSomethingRemote" actionListener="#{controllerBean.doSomething()}" process="@this" />

    <h:body>
        <h:form>
        
            <c:forEach items="#{controllerBean.elementList}" var="element">
                <p:outputLabel value="Element: #{element}"/><br/>
            </c:forEach>
            
            <p:commandButton value="call Remote Command" onsuccess="doSomethingRemote();" process="@none" />
        </h:form>
    </h:body>

</html>

and a Java backend like:

@Named
public class ControllerBean {

    private static final Logger LOG=Logger.getLogger(ControllerBean.class);

    private List<String> elementList=new ArrayList<>();

    public ControllerBean() {
        elementList.add("First");
        elementList.add("Second");
        elementList.add("Third");
    }

    public List<String> getElementList() {
        LOG.info("getElementList() is called");
        return elementList;
    }

    public void doSomething() {
        LOG.info("doSomething() is called");
    }
}

Each time I press the button, calling the remote command, the method getElementList() is called three times, then one time doSomething() and then a fourth call of getElementList().

Edit(1): I know that getter can be called multiple times, but why is any getter called if I just call a remote comand and do not need to render or update anything of my page? And why is it only done for c:forEach?
If I just replace the whole c:forEach with e. g.

<p:outputLabel value="Element: #{controllerBean.elementList.get(0)}"/>

I do not have this behaviour at all!

Martin Metz
  • 308
  • 1
  • 3
  • 13
  • I know that a getter is not only called once but multiple times during rendering a page. But my question is, why is anything rendered when I just call a remote command? I do not have any update and no need for a render at all! – Martin Metz May 16 '23 at 11:36

0 Answers0