第一次使用JSF,我对getRowData()
的工作方式感到困惑。我在互联网上搜索时发现的所有内容是,它返回了数据表中的“当前选定的行”,但我无法确定它如何决定哪一行是选定的行。例如,我有一个用于数据表的代码:
JSP:
<h:dataTable value="#{backing_student.eligibleCoursesList}" var="cdto"
binding="#{backing_student.eligibleCoursesDataTable}"
id="eligibleCoursesDataTable" rules="all" frame="box"
border="2">
<%--
oracle-jdev-comment:Faces.RI.DT.Class.Key:hu.elte.pgy2.BACNAAI.UranEJB.CourseDTO
--%>
<h:column>
<f:facet name="header">
<h:outputText value="Kurzuskód"
binding="#{backing_student.outputText7}"
id="outputText7"/>
</f:facet>
<h:outputText value="#{cdto.cid}"/>
</h:column>
<!-- couple more plain text columns like the above -->
</h:column>
<h:column>
<h:commandButton value="Felvétel"
actionListener="#{backing_student.addSelfToCourseListener}"/>
</h:column>
</h:dataTable>
后备豆:
public class BackingStudent {
private HtmlDataTable eligibleCoursesDataTable;
private List<CourseDTO> eligibleCoursesList;
// ...
public void addSelfToCourseListener(ActionEvent actionEvent) {
HtmlCommandButton thisButton = (HtmlCommandButton)actionEvent.getComponent();
CourseDTO cdto = (CourseDTO)(eligibleCoursesDataTable.getRowData());
thisButton.setValue(cdto.getCid());
}
}
这样,每当我单击任一行中的按钮时,所有按钮的文本都将更改为该行第一列中的值。
getRowData()
如何确切地知道要从表中获取哪一行?额外的问题:为什么每个按钮的文字都会改变?
最佳答案
JSF标签使组件树内置在内存中。例如,dataTable
标记由UIData实例(HtmlDataTable
是其子类)支持。 UIData
的作用是迭代DataModel。对于JSF lifecycle的每个阶段,它将执行以下操作:
//not the real code
for(int i=0; i<model.getRowCount(); i++) {
model.setRowIndex(i);
Object row = model.getRowData();
externalContext.getRequestMap().put(var, row);
//invoke phase-specific action
externalContext.getRequestMap().remove(var);
}
在您的情况下,
var="cdto"
,这就是为什么任何使用EL解析为行bean的控件都将获得正确值的原因。构建组件树时,
UIData
不会在每行添加另一个子控件。它使用一组控件并更改基础模型数据。尽管是UIData
performs some actions to preserve child state,但对于HtmlCommandButton实例,默认情况下不会这样做(因为默认情况下),因为它没有实现EditableValueHolder。要解决此问题,请使用EL表达式将值绑定到模型(可能是某些row bean属性)。
注意:通常,您不必在必须将任何
javax.faces...
类导入到模型bean中的地方编写代码,但是您必须在模型设计中花点时间。