0

次の 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>

また、次のマネージド 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 が正常に動作して結果セットを返すように見えますが、resultsTable にレコードが表示されません。さらに、プロセスメソッドを更新しているときに、

studentProvider.findStudent(pattern)

何度も電話。メソッド呼び出しの数は、「resultsTable」のレコード数に依存すると思います。

インジェクションの前は、ハード リンクされたオブジェクトを使用すると、すべて正常に動作します。どうしたの?

ところで、私は一つのことを理解できません。ボタンがあるとしましょう

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

「resultsTable」の各レコード (詳細については、前の xhtml リストを参照してください)。このボタンが機能しない場合があることがわかりました。resultsTable が最初に空の場合 - ボタンは機能しませんが、resultsTable が空でない場合 - ボタンは機能します。では、ボタンを常に機能させるにはどうすればよいですか?

4

1 に答える 1

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)}"

2 番目の質問に答えるには:なぜ JSF がゲッターを複数回呼び出すのか、これは、ビジネス ロジック メソッドをゲッターに (遅延読み込みなしで) 配置することは悪い考えのように思われることを意味します (別の関連する質問: JSF がセッターとゲッターを複数回呼び出す)。

于 2012-10-16T10:52:29.237 に答える