2013-01-18 27 views
3

我已經偶然發現了一個至少對我來說意想不到的行爲。當使用ui:repeat時,似乎我可以從外部訪問var。Magic 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> 

碼 - 豆

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中。這怎麼可能?

+0

問[這傢伙](http://stackoverflow.com/a/1137911/1530938)。舊的編譯時間V渲染時間差異:) – kolossus

+0

由於我對JSF的更細粒度工作的瞭解有限,我仍然不明白ui:repeat var在組件外突然有效。我以前的理解是,它不應該。 – nivis

回答

6

這是一個在Mojarra的錯誤。其UIRepeat組件在恢復視圖階段忘記在迭代結束時從請求範圍中刪除迭代變量。它不適用於例如MyFaces。

你不應該依賴你的業務代碼。請注意,<h:dataTable>不存在此問題,它會在迭代結束時通過((UIData) component).setRowIndex(-1) in encodeEnd() method從請求範圍中正確刪除迭代變量。

+0

感謝BalusC的澄清。現在我將轉向另一種解決方案。 – nivis