第一次使用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中的地方编写代码,但是您必须在模型设计中花点时间。

10-04 18:33