Request Scoped Producer and ajax partial rendering does not work as expected
ruenagel_frank Dec 7, 2013 10:19 AMAn ajax commandlink or commandbutton calls a bean method to add an entry to a list, which is shown in the html. Then it renderes the list's id. The list is produced by a @requestScoped producer method.
If commandlink and list both are in the same form, the producer is called before the adder: the list on screen is not updated with the just added value.
If (1) the commandlink is in a different form or
(2) the commandlink is decorated with execute="@this", then it works as expected: the adder-method is called before the producer is called.
This behaviour is at least inconsistent and unexpected.
Tested with
Tomcat 7, org.jboss.weld.servlet 2.0.4/2.1, Richfaces 4.3.4
JBoss AS 7.1.1.Final with Richfaces 4.2.3
Is this a bug or have I missed something?
Here is the xhtml, remove execute="@this" to reproduce it:
<h:form id="myform0"> <a4j:commandButton execute="@this" render="tableidx" action="#{test.addToListOfStrings2('p')}" value=" Add a Line" /> <br /> <br /> <a4j:commandLink execute="@this" render="tableidx" action="#{test.addToListOfStrings2('l')}"> Add a Line </a4j:commandLink> <br /> <br /> <h:panelGroup id="tableidx"> <rich:dataTable var="_item" value="#{MYLISTOFSTRINGSX}" id="tableidxinner"> <rich:column> <h:outputText value="#{_item}"></h:outputText> </rich:column> </rich:dataTable> </h:panelGroup> </h:form>
Java:
import java.io.Serializable; import java.util.ArrayList; import java.util.Date; import java.util.List; import javax.enterprise.context.Dependent; import javax.enterprise.context.RequestScoped; import javax.enterprise.context.SessionScoped; import javax.enterprise.inject.Produces; import javax.inject.Named; import org.apache.log4j.Logger; @Named @SessionScoped public class Test implements Serializable { private static final long serialVersionUID = 1L; private static final Logger log = Logger.getLogger(Test.class); private List<String> listOFStrings = new ArrayList<>(); @Produces @Named("MYLISTOFSTRINGSX") @RequestScoped public List<String> fetchMyListOfStrings() { log.info("Fetch!"); return new ArrayList<>(listOFStrings); // return new object to simulate database fetches } public void addToListOfStrings2(String v) { log.debug("Add TO List of Strings"); listOFStrings.add(new Date().getTime() +"" +v); } }