无法理解<p:datatable>更新过程</p:datatable>

时间:2012-10-16 05:51:35

标签: ajax java-ee jsf-2 primefaces

我有以下xhtml文档:

  <h:body>
   <ui:composition template="templates/layout.xhtml">
      <ui:define name="content">
        <c:if test="#{sessionBean.userCode > 0}">
          <h:form id="findStudentForm">
            <p:outputPanel id="resultsPanel">
              <c:if test="#{studentsBean.student != null}">
                <h2><h:outputText value="#{studentsBean.student.fullName}"/></h2>
                <h3>Personal data</h3>
                  . . .
                <p align="center">
                <p:commandButton value="Search students" update="@form">
                  <f:setPropertyActionListener value="#{null}" 
                    target="#{studentsBean.student}"/>
                </p:commandButton>
                </p>
              </c:if>
              <c:if test="#{studentsBean.student == null}">
                <h2>Student search</h2>
                  . . .
                <p align="justify">
                  First name
                  <h:inputText value="#{studentsBean.pattern}"/>
                  <p:commandButton value="Поиск" update="resultsPanel"/>                  
                </p>
                <p:dataTable id="resultsTable" var="student" 
                   value="#{studentsBean.studentsList}" 
                             widgetVar="studentsTable" emptyMessage="No records found">
                  . . . 
                  </p:column>
                  <p:column headerText="Actions">
                    <p:commandButton value="Details" update="@form">
                      <f:setPropertyActionListener value="#{student}" 
                        target="#{studentsBean.student}"/>
                    </p:commandButton>
                  </p:column>  
                </p:dataTable>
              </c:if>
            </p:outputPanel>
          </h:form>
        </c:if>
        <c:if test="#{sessionBean.userCode == 0}">
          <ui:include src="templates/include/error.xhtml"/>
        </c:if>
      </ui:define>  
    </ui:composition>
  </h:body>

我还有以下Managed Bean(StudentsBean):     。 。

@Named(value = "studentsBean")
@RequestScoped
public class StudentsBean {

  @Inject
  SessionBean session;
  private Student student = null;
  private String pattern = "";
  private String groupName = "";
  @Inject
  private StudentInterface studentProvider;

  . . .

  public String getPattern() {
    return pattern;
  }

  public void setPattern(String pattern) {
    this.pattern = pattern;
  }

  public List<Student> getStudentsList() {
    List<Student> result = new ArrayList<Student>();
    if (studentProvider != null) {
      try {
        result = studentProvider.findStudents(pattern);
      } catch (StudentException e) {
        session.printError(e.getMessage());
      }
    }
    return result;
  }
  . . .

最后,我有一个班级StudentsProvider:

public class StudentProvider implements StudentInterface {

  private Connection connection = null;

   . . .

  @Override
  public List<Student> findStudents(String pattern) throws StudentException {
    List<Student> result = new ArrayList<Student>();
    String addon = "";
    if (pattern.trim().isEmpty()) {
      addon = "TOP 10 ";
    }
    try {
      PreparedStatement statement = connection.prepareStatement(
              "SELECT " + addon + "st_pcode, gr_Name, st_FullName "
              + "FROM students, groups WHERE (st_grcode = gr_pcode) AND (st_FullName LIKE ?) "
              + "ORDER BY gr_Name, st_FullName;", ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY);
      statement.setString(1, pattern + "%");
      ResultSet rs = statement.executeQuery();
      while (rs.next()) {
        result.add(getStudent(rs.getString("st_pcode")));
      }
      rs.close();
      statement.close();
    } catch (Exception e) {
      throw new StudentException("Error reading list: " + e.getMessage());
    }
    return result;
  }

  public StudentProvider() throws StudentException {
    try {
    ConnectionProvider provider = new ConnectionProvider();
    connection = provider.getConnection();
    } catch (ConnectionException e) {
      throw new StudentException("Connect error: " + e.getMessage());
    }
  }

  @Override
  public void finalize() throws Throwable {
    connection.close();
    super.finalize();
  }
}

如果变量“pattern”为空字符串,则PreparedStatement返回10个“第一”记录。但如果“模式”有内容 - PreparedStatement会找到一些记录。在调试期间,似乎PreparedStatement运行良好并返回结果集,但在“sultsTable”中没有显示任何记录。另外,我发现,在更新流程方法时

studentProvider.findStudent(pattern)

多次打电话。我认为,这个方法调用的数量取决于“resultsTable”中的记录数。

在注射之前,使用硬链接对象一切正常。怎么了?

顺便说一下,我无法理解一件事。说,我有一个按钮

<p:commandButton value="Details" update="@form">
    <f:setPropertyActionListener value="#{student}" 
        target="#{studentsBean.student}"/>
</p:commandButton>

在“resultsTable”的每条记录中(有关详细信息,请参阅之前的xhtml列表)。我发现,这个按钮有时不起作用。 如果resultsTable在开头为空 - 按钮不起作用,但如果resultsTable不为空 - 按钮工作。那么如何让按钮始终有效?

1 个答案:

答案 0 :(得分:2)

更好的方法是(只是草图):

// an action method in your backing bean.
// This will call your search method and set the values behid your dataTable
public void searchStudents(String pattern) {
    setStudentsList(findStudent(pattern));
}

通话结束后更新您的dataTable:

<p:commandButton update="resultsTable" action=#{studentProvider.findStudent(pattern)}"

回答你的第二个问题:Why JSF calls getters multiple times,这意味着将你的业务逻辑方法放入getter(没有延迟加载)似乎是一个坏主意(另一个相关问题:JSF calling setter & getter multiple times)。