I have stumbled upon an, at least for me, unexpected behaviour. When using an ui:repeat, it seems I can access the var from outside.
Code - Page:
<f:metadata>
<f:event type="preRenderView" listener="#{xTest.init()}" />
</f:metadata>
<h:form id="xTestForm">
<h:panelGroup layout="block">
Track: #{trk.name}
</h:panelGroup>
<table>
<ui:repeat
value="#{xTest.trackList}"
var="trk">
<tr>
<td>#{trk.name}</td>
<td>
<p:commandLink
actionListener="#{xTest.setTrack(track)}"
value="test"
update=":xTestForm" />
</td>
</tr>
</ui:repeat>
</table>
</h:form>
Code - Bean
package beans;
import dao.DAOFactory;
import dao.track.TrackDAO;
import dto.Track;
import exceptions.DAOException;
import java.io.Serializable;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ViewScoped;
import javax.faces.context.FacesContext;
import util.MessageUtil;
@ManagedBean
@ViewScoped
public class xTest implements Serializable {
private DAOFactory daoFactory = Config.getInstance().getDAOFactory();
private TrackDAO trackDAO;
private Track track = new Track();
private MessageUtil msg = new MessageUtil();
private List<Track> trackList = new ArrayList();
public xTest() {
trackDAO = daoFactory.getTrackDAO(true);
}
public void init() {
if (!FacesContext.getCurrentInstance().isPostback()) {
try {
trackList = trackDAO.listByAlbumid(241);
} catch (SQLException | DAOException ex) {
msg.setErrorMessage(ex);
}
}
}
public List<Track> getTrackList() {
return trackList;
}
public void setTrack(Track track) {
this.track = track;
}
}
If I click a link in the list of tracks, the track name will be displayed in the panelGroup. How is this possible?
This is a bug in Mojarra. Its UIRepeat
component forgets to remove the iteration variable from the request scope by end of iteration during restore view phase. It doesn't work that way in for example MyFaces.
You shouldn't rely your business code on it. Note that <h:dataTable>
doesn't have this problem, it properly removes the iteration variable from the request scope by end of iteration by ((UIData) component).setRowIndex(-1)
in encodeEnd()
method.
8 years later someone reported this to PrimeFaces so I opened a Mojarra issue and a PR to fix the issue.
Mojarra Issue: https://github.com/eclipse-ee4j/mojarra/issues/4830
Mojarra PR: https://github.com/eclipse-ee4j/mojarra/pull/4831
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With