这是我的场景:
A h:在后台bean中带有HtmlDataTable对象绑定的dataTable。在h:列内部的命令按钮触发的操作方法中调用HtmlDataTable的getClientId是给我数据表id和行索引作为clientId。如果数据表id是'table', getClientId()返回table:0(或table:1, table:2…)(取决于命令按钮所在的行索引)
我期望得到'table'作为clientId,因为绑定的表总是相同的。
当我用数据表外部的按钮调用相同的方法时,我得到'table'。这对我来说是正确的,但我不明白为什么如果动作来自一个uiccolumn按钮,我得到表:rowIndex.
JSF页面是:
<h:form prependId="false">
<h:dataTable id="table" value="#{sessionBean.dummyData}" var="row" binding="#{sessionBean.dataTable}">
<h:column>
<f:facet name="header">
ROW ID
</f:facet>
#{row.longValue()}
</h:column>
<h:column>
<f:facet name="header">
ACTION 1
</f:facet>
<h:commandButton id="btn1" value="REFRESH CLIENT FROM UIColumn" >
<f:ajax execute="@this" render="output" listener="#{sessionBean.testAction()}" />
</h:commandButton>
</h:column>
</h:dataTable>
<h:commandButton id="btn2" value="REFRESH CLIENT outside from data table" >
<f:ajax execute="@this" render="output" listener="#{sessionBean.testAction()}" />
</h:commandButton>
<h:outputText id="output" value="#{sessionBean.clientId}" />
</h:form>
支持Bean: @ManagedBean
@SessionScoped
public class SessionBean {
private List<Long> dummyData;
private String clientId;
private HtmlDataTable dataTable;
public SessionBean() {
dummyData = new ArrayList<Long>();
}
@PostConstruct
public void postConstruct(){
for(int i = 0; i < 5; i++){
dummyData.add(new Long(i));
}
}
public String getClientId() {
return clientId;
}
public void setClientId(String clientId) {
this.clientId = clientId;
}
public void testAction(){
clientId = this.dataTable.getClientId();
}
public List<Long> getDummyData() {
return dummyData;
}
public void setDummyData(List<Long> dummyData) {
this.dummyData = dummyData;
}
public HtmlDataTable getDataTable() {
return dataTable;
}
public void setDataTable(HtmlDataTable dataTable) {
this.dataTable = dataTable;
}
}
提前感谢。我想知道这是否是正常的JSF行为。
我对JSF代码进行了一些挖掘,是的,似乎他们有意将其设计成这种工作方式。在服务器上的JSF生命周期处理期间,HtmlDataTable对象的clientId不断变化,因为它包含"当前选定"行的索引。并且,在"Invoke Application"生命周期阶段,在调用Ajax处理程序(即"testAction"方法)之前不久,JSF框架将HtmlDataTable的行索引设置为与所单击按钮所在的行相对应。
据我所知,从JavaDoc的UIData::getClientId(FacesContext)方法(由HtmlDataTable继承)的基本原理,包括行索引在UIData组件的clientId,是为了避免clientId冲突子组件属于不同的行。