3

ボタンは、JSFビューでJSTLコードを削除した場合にのみ、アクションメソッドを呼び出します。これはライフサイクルの問題であることがわかっていますが、原因/問題がわかりません。それがこの振る舞いを引き起こすので、私は誹謗中傷するのが好きです。

コードの表示は正常に機能します

    <f:metadata>            
<f:viewParam name="idAsociacion" value="#{msgUsuario.asociacion}" converter="#
               {asociacionConverter}"
        converterMessage="#msg['aplicacion.asociacion.error.converter']}" required="true" 
        requiredMessage="#{msg['aplicacion.asociacion.error.required']}" />
<f:viewParam name="idMsg" value="#{msgUsuario.mensajeRespondido}" converter="#
     {mensajeConverter}" converterMessage="#{msg['aplicacion.mensaje.error.converter']}" 
     required="true" requiredMessage="#{msg['aplicacion.mensaje.error.required']}" />
    </f:metadata>

    <ui:decorate template="/WEB-INF/templates/mainUsuario-template.xhtml">
    <ui:define name="title">        
    <h:outputFormat value="#{msg['usuario.escribirMsj.title']}">
        <f:param value="#{msgUsuario.asociacion.nombre}" />
    </h:outputFormat>
    </ui:define>

    <ui:param name="descripcionView" value="#{msg['usuario.escribirMsj.descripcion']}" />

     <ui:define name="content">
<h:panelGroup layout="block"
          id="escribirMensajeContainer"styleClass="escribirMensajeContainer">
    <h:form>
        <p:panelGrid>
        <p:row>
        <p:column>
        <h:outputLabel for="texto" value="#{msg['usuario.escribirMsj.mensaje']}" 
                 styleClass="labelInput" />
        </p:column>
        </p:row>

        <p:row>
        <p:column>
        <p:inputTextarea  autoResize="true" cols="80" rows="15" id="texto" 
             maxlength="500" value="#{msgUsuario.texto}">

        </p:inputTextarea>
            </p:column>
        </p:row>

        <p:row>
    <p:column>
    <h:message for="texto" id="messageMensajeError" styleClass="messageError" />
    </p:column>                         
        </p:row>


        <p:row>         
             <p:column>
    <p:commandButton action="#{msgUsuario.enviar}" 
               alt="#{msg['usuario.escribirMsj.alt.enviar']}" tabindex="2" title="#
      {fn:replace(msg['usuario.escribirMsj.title.enviar'],0,msgUsuario.asociacion.nombre)}" 
       value="#{msg['usuario.escribirMsj.enviar']}" />
</p:column>                         
    </p:row>                            
    </p:panelGrid>
    </h:form>
    </h:panelGroup>         
    </ui:define>
    </ui:decorate>
    </html>

しかし、JSTLを追加すると、以下のようになります。メッセージが応答されないため、ビューは正常にレンダリングされますが、ボタンがアクションメソッドを呼び出したり、ビューがリロードされたりすることはありません。

      <c:choose>
      <c:when test="#{msgUsuario.mensajeRespondido.respondido==false}">
        <h:form>
        <p:panelGrid>
        <p:row>
        <p:column>
        <h:outputLabel for="texto" value="#{msg['usuario.escribirMsj.mensaje']}" 
                 styleClass="labelInput" />
        </p:column>
        </p:row>

        <p:row>
        <p:column>
        <p:inputTextarea  autoResize="true" cols="80" rows="15" id="texto" 
             maxlength="500" value="#{msgUsuario.texto}">

        </p:inputTextarea>
            </p:column>
        </p:row>

        <p:row>
    <p:column>
    <h:message for="texto" id="messageMensajeError" styleClass="messageError" />
    </p:column>                         
        </p:row>


        <p:row>         
             <p:column>
    <p:commandButton action="#{msgUsuario.enviar}" 
               alt="#{msg['usuario.escribirMsj.alt.enviar']}" tabindex="2" title="#
      {fn:replace(msg['usuario.escribirMsj.title.enviar'],0,msgUsuario.asociacion.nombre)}" 
       value="#{msg['usuario.escribirMsj.enviar']}" />
</p:column>                         
    </p:row>                            
    </p:panelGrid>
    </h:form>
    </c:when>
    <c:otherwise>
         <h:outputText value="MESSAGE RESPONSED" />
    </c:otherwise>
    </c:choose>

注:変換は2つの場合に正常に機能します。

ManagedBeanコード

  @ManagedBean(name="msgUsuario")
  @ViewScoped
  public class EscribirMensajeUsuarioView implements Serializable {

private static final long serialVersionUID = 1L;
private static final Logger logger=Logger.getLogger(EscribirMensajeUsuarioView.class);

private Asociacion asociacion;

private Mensaje mensajeRespondido;

private Usuario usuario;


private String texto;

private boolean usuarioBloqueado;

@ManagedProperty(value="#{mensajeBO}")
private MensajeBO mensajeBo;

@ManagedProperty(value="#{usuarioBO}")
private UsuarioBO usuarioBo;


/* Never invoked with JSTL code in the view */

public String enviar(){
    logger.info("EscribirMensajesUsuarioView.enviar");

    TipoMensaje tipoMensaje=null;
    Mensaje mensaje=this.mensajeRespondido;

    .................
            .................
            .................
      }


/* Getters and Setters */
   }

このバルスクのコメントを読んだ

「JSFとJSTLは、コーディングから期待されるように同期して実行されません。JSTLはビューのビルド時(JSFコンポーネントツリーにデータが入力されるとき)に実行され、JSFはビューコンポーネントツリーのレンダリング時に実行されます( HTML出力を生成する場合)次のように視覚化できます。JSTLは最初に上から下に実行され、次に結果をJSFに渡し、JSFは再び上から下に実行されます。」

たとえば、dinamyc datatableでこれを理解していますが、この場合は理解していません。JSTLはJSFツリーでmensajeRepetidoが終了するというビューを細かくレンダリングしますが、ボタンはメソッドを呼び出しません。ただし、ビューのリロードとmensajeRepetidoはコンバーターによって再び終了します。

敬具。

4

1 に答える 1

3

この問題は、JSTL属性をビュースコープのマネージドBeanプロパティにバインドしているために発生します。これは、部分的な状態保存がオフになっている場合にのみ機能します。部分的な状態保存がオンになっている場合(デフォルトで)、JSTL属性は、JSFビューステートに格納され、JSFによって使用されるインスタンスではなく、ビュースコープBeanの独自の2番目のインスタンス(すべてのプロパティがデフォルトに設定されています!)を取得しますコンポーネント。

通常の方法の代わりにJSFコンポーネントのrendered属性を使用し、JSTLを使用してビューの構築を制御するだけで、ビューのレンダリングを制御することはできません。

<h:form rendered="#{not msgUsuario.mensajeRespondido.respondido}">
    ...
<h:form>
<h:panelGroup rendered="#{msgUsuario.mensajeRespondido.respondido}">
     <h:outputText value="MESSAGE RESPONSED" />
</h:panelGroup>      

参照:

于 2012-05-25T16:33:23.393 に答える