魔法ui:repeat变量

4

我遇到了一个对我来说意外的行为。在使用ui:repeat时,似乎我可以从外部访问var。

代码-页面:

<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>

代码 - 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;
    }
}

如果我在曲目列表中点击一个链接,曲目名称将被显示在panelGroup中。这是如何实现的?

这个人。编译时和渲染时的年代差异 :) - kolossus
尽管我对JSF的更细节的工作原理知识有些局限,但我仍然不明白为什么ui:repeat var突然在组件外部有效。我的先前理解是它不应该这样。 - nivis
2个回答

7
这是Mojarra中的一个错误。在恢复视图阶段结束迭代时,其UIRepeat组件忘记从请求范围中删除迭代变量。例如,在MyFaces中不会出现这种情况。
您不应该依赖它来编写业务代码。请注意,<h:dataTable>没有这个问题,它通过((UIData) component).setRowIndex(-1)encodeEnd()方法中正确地从请求范围中删除了迭代变量。

感谢BalusC的澄清。现在我将转向另一个解决方案。 - nivis

2

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接