0

私は次のコードを持っています:

<h:form>
    <h:inputText id="inputField" value="#{bean.myProperty}">
        <f:validateLongRange
            minimum="#{bean.minimum}"
            maximum="#{bean.maximum}"/>
    </h:inputText>
    <h:commandButton id="submit" value="Submit" >
        <f:ajax execute="inputField" render="outputField errors" />
    </h:commandButton>
    <h:outputText id="outputField" value="#{bean.myPropertyFormatted}"/>
    <h:message id="errors" for="inputField"/>
</h:form>

inputTextの検証に失敗した場合、ユーザーからoutputTextを削除/非表示にします。これを行うための最もエレガントで将来のリファクタリングに耐える方法は何ですか?

outputText要素に属性rendered="#{!facesContext.validationFailed}"を設定しようとしましたが、古いテキストを変更せずに、outputText要素が再レンダリングされるかどうかを決定するだけです。ただし、validateLongRange検証が失敗した場合、ユーザーは検証エラーメッセージを表示し、以前の有効な入力に基づく古い出力メッセージを表示することに関心がないため、ユーザーからoutputTextを完全に削除/非表示にします。それでも、Beanに格納されている値。

4

3 に答える 3

5

JSFの経験則として、条件付きで何かをレンダリングする場合は、それをコンテナーコンポーネント()でラップし、コンテナーコンポーネント<foo:panel/>をajax更新のターゲットにする必要があります。

<h:form>
   <h:inputText id="inputField" value="#{bean.myProperty}">
      <f:validateLongRange
        minimum="#{bean.minimum}"
        maximum="#{bean.maximum}"/>
   </h:inputText>
   <h:commandButton id="submit" value="Submit" >
      <f:ajax execute="inputField" render="thePanel errors" />
   </h:commandButton>
   <h:panelGrid id="thePanel">
   <h:outputText rendered="#{!facesContext.validationFailed}" id="outputField" value="#{bean.myPropertyFormatted}"/>
   </h:panelGrid>
   <h:message id="errors" for="inputField"/>
</h:form>

コンポーネントをajaxで更新するには、そのコンポーネントがブラウザーのDOMに既に存在している必要があります。これがajaxの動作方法です。したがって、ビューが最初にレンダリングされたとき、条件がfalseと評価さoutputFieldれているため、は存在しません。renderedしたがって、前述の理由により、その後のajax更新のリクエストは失敗します。コンテナコンポーネントの戦略は、以前にあったものに関係なく、マークアップの領域の包括的な更新があることを確認することです

于 2013-02-28T17:06:06.787 に答える
3

問題はrendered、オブジェクトに属性を設定し、その値がfalseである場合、コンポーネントはレンダリングされず、再レンダリング(または更新)できないため、コンポーネントツリーに含まれないことです。解決策は、コンポーネントを内部に設定しUIContainer、コンテナをレンダリングすることです。

<h:commandButton id="submit" value="Submit" >
    <f:ajax execute="inputField" render="pnlResult" />
</h:commandButton>
<h:panelGrid id="pnlResult">
    <h:outputText id="outputField" value="#{bean.myPropertyFormatted}"
        rendered="#{not facesContext.validationFailed}" />
    <h:message id="errors" for="inputField"/>
</h:panelGrid>
于 2013-02-28T17:06:47.730 に答える
1

kolossusとLuiggiMendozaの優れた回答に基づいて、私は次のことを行うことになりました。

<h:form>
    <h:inputText id="inputField" value="#{bean.myProperty}">
        <f:validateLongRange
            minimum="#{bean.minimum}"
            maximum="#{bean.maximum}"/>
    </h:inputText>
    <h:commandButton id="submit" value="Submit" >
        <f:ajax execute="inputField" render="outputField errors" />
    </h:commandButton>
    <h:panelGroup layout="block" id="outputGroup">
        <h:outputText id="outputField" value="#{bean.myPropertyFormatted}" rendered="#{not facesContext.validationFailed}"/>
        <h:message id="errors" for="inputField"/>
    </h:panelGroup>
</h:form>

私のWeb開発者の経歴が、テーブルベースのレイアウトのアイデアに身震いするので、h:panelGroup代わりに選択しました。h:panelGridと一緒に表示されますがlayout="block"h:panelGroupとしてレンダリングされますが<div/>h:panelGridとしてレンダリングされます<table/>

于 2013-02-28T20:14:23.653 に答える