JSF 2.0: Render campos de formulario con los datos iniciales utilizando granos de petición de ámbito de (a datos específicos del servidor de actualización de componente de corriente)

StackOverflow https://stackoverflow.com/questions/3812685

Pregunta

Un caso bastante normal:

tiene un componente 'portlets' compuesta que tiene dos estados: expansión y de compresión. Portlets comienzo como expandieron, pero el usuario puede contraerlos pulsando sobre ellos. Este estado debe ser guardado en la sesión, por lo que una vez que se actualice la página o usuario navega a una nueva, los portlets recordar si se expanden / colapsado.

Este es el núcleo del problema :? ¿Cómo poner en práctica tales realidad que se puede insertar en la página varias veces en un componente, de ahorro de estado

Algunos antecedentes / ideas:

Implementación de un portlet ahorro de estado se logra fácilmente mediante el uso de un bean de sesión con ámbito. También se ha corregido el número de módulos de función podría ser apoyada mediante la creación de un número fijo de beans de sesión con ámbito o declarar propiedades diferentes en un solo frijol. Sin embargo, no quiero mencionar incluso por qué los enfoques es mala.

Mi idea inicial de esta era crear un mapa (o alguna estructura del objeto) bajo bean de sesión único para mantener los estados para todos los módulos de función. Sin embargo, no puedo referirse directamente a estos datos de JSF (de modo que JSF también actualizarlos). Consideré escribir un captador específico / definidor para ir a buscar / actualizar el valor justo en el mapa, pero eso no es posible, ya que no hay datos que identifican durante la ejecución de los captadores y definidores.

Sin embargo, es probable que sea claro que necesito para salvar a los estados en un bean de sesión. Puedo hacer lo bastante facilidad mediante la publicación de un formulario con f:ajax y ejecución de un método especial que utiliza listener y los datos presentados de ahorro de estado. Con el fin de soportar múltiples instancias de componente, que podría utilizar (varias instancias de) un grano de solicitud de ámbito de manejar cada colapso expandir /. Sin embargo, con el fin de publicar en realidad los datos que identifica la portlets y su estado, que necesitan primera inserción en los campos de formulario en tiempo de render.

Por lo tanto, la manera de proporcionar realidad cada módulo de función con los datos correctos en render en tiempo (en realidad sólo el estado booleano / enumeración en este caso, pero hay que considerar un caso en el que se deben manejar más datos)?

Parece que:

  • h:inputHidden y h:inputText no apoyan el valor de ajuste inicial distinta de que el valor-atributo (que apunte a #{portletBean.portletState}).
  • No puedo cargar automáticamente los granos de solicitud con los valores iniciales correctas en el tiempo de creación, ya que no hay información de identificación disponibles.

Una vez más se siente como que me falta algo ... punteros?

supongo que al menos una de las respuestas sería el uso de UIComponent en lugar de componentes compuestos, pero me gustaría tener esto como componente compuesto, ya que contiene una gran cantidad de elementos HTML primas.

Actualización:

  • bastante similar cuestión, con la sugerencia de usar frijol vista con ámbito. No creo sin embargo, esto es viable aquí,.
¿Fue útil?

Solución 3

I utiliza un resuelto previamente truco para llamar a un método de frijol de JS :

Creado una forma vacía, invisible, con h:commandButton y f:ajax su interior llamando listener.

Creado un botón separado para el lanzamiento del evento expandir / contraer. A partir de ese botón de iniciar el método de Javascript, que anima a la expansión / colapso y al mismo tiempo hace clic en el botón oculto en el interior de la forma. Todos los datos necesarios se envían utilizando el atributo listener. Oyente se dirige a un bean de sesión, lo que comprueba / actualiza un mapa de estados, identificado por ID de cliente de componentes.

Esto es bastante simple, es de extrañar por eso que no se daba cuenta eariler ...

Sin embargo, todavía lejos de ser perfecto y que no responde a la forma de los granos de petición con ámbito podrían ser iniciadas con valores predeterminados para utilizarlos como forma de almacenamiento / transporte.

Otros consejos

Tengo un par de trucos posibles para esto. Voy a publicar aquí, pero no creo que estos son realmente el camino a seguir:

Uso javascript para campos de formulario conjunto con los datos correctos directamente después de la prestación:

window.addEvent('domready', function() {
    var portletState = '#{portletBean.getPortletState(cc.attrs.clientId)}';
    // find the field and set the data...
});

Se siente muuy hacky. No quiero tomar esta ruta.

mapa de atributos de uso de componentes para contener los datos:

<cc:interface>
    <cc:attribute name="portletState" default="#{portletBean.getPortletState(cc.attrs.clientId)}" />
</cc:interface>

El acceso que a partir de código:

public void stateChangedCallback(String clientId) {
    UIComponent component = FacesContext.getCurrentInstance().getViewRoot().findComponent(clientId);
    String state = (String) component.getAttributes().get("portletState");
}

Además, no se siente bien. Además no estoy seguro si funciona (en realidad se puede utilizar en su defecto EL-atributo).

Uso del componente de mapa atributo para contener los datos poniendo a su disposición al llamar al componente:

<portlet:portlet id="specificPortlet">
    <f:attribute name="portletState" value="#{portletBean.getPortletState(component.clientId)}" />
</portlet:portlet>

Una vez más, muy torpe y duplica su código.

Puede hacerlo utilizando taglibs, puede pasar parámetros en etiquetas:

añadir lo siguiente a su taglib:

<tag>
    <tag-name>date</tag-name>
    <source>components/date.xhtml</source>
</tag>

A continuación, aquí es el contenido de componentes / date.xhtml

<ui:composition name="date_template">
    <h:panelGrid id="#{id}Panel" columns="1" border="0" cellpadding="0" cellspacing="0">
        <rich:calendar immediate="true" id="#{id}" popup="true" datePattern="dd.MM.yyyy"
                        enableManualInput="true" showApplyButton="true" cellWidth="12px" cellHeight="11px" style="width:100px"
                        value="#{dateForm.date}" required="#{required}" readonly="#{readonly}" validator="#{dateForm.validateDate}">
            <a4j:support event="onchanged" reRender="#{id}Panel,#{reRenderDate}"/>
            <ui:insert />
        </rich:calendar>

        <rich:message for="#{id}" errorClass="error" />
    </h:panelGrid>
</ui:composition>

Y a continuación, utiliza esto como:

<adse:date id="dateTransfert" required="true"
           dateForm="#{dossierBean.dateTransfert}"
           readonly="false" reRenderDate="montantAncien,montantNouveau,montantEmolument">
     <a4j:support event="oninputblur" reRender="dateTransfertPanel,montantAncien,montantNouveau,montantEmolument"/>
</adse:date>

En este caso, FormFecha se pasa en, este es un objeto, y en el taglib usamos propiedades de ese objeto (dateForm.date). También tenga en cuenta el. que puede utilizarse para incluir otros elementos en el XHTML

Así pues, usted podría pasar en el contexto para cada portlet. Incluso se puede hacer de este estándar por tener portletBean como una superclase que define el método getPortletState ().

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top