p:autocompletar itemLabel lanza “de La clase java.lang.Cadena’ no tiene la propiedad ‘etiqueta’.”

Que me voy a cambiar de IceFaces para PrimeFaces (yo realmente quería cambiar a RichFaces, pero que causan un error en la nueva versión, yo no) y estoy havinng algunos dificults de aplicar correctamente primefaces de autocompletar. De acuerdo a su manual solo necesito implementar un método que devuelve una lista de objetos, y en este caso de un convertidor es necesario.

La lista me estoy volviendo está una lista de javax.las caras.modelo.SelectItem, yo realmente no puedo entender por qué necesito crear un convertidor a esto, pero vamos a seguir. He creado un sencillo convertidor sólo para probar, pero primefaces no reconoce mi convertidor y devuelve este error en el navegador:

/recursos/componentes/popups/popupBuscaPessoa.xhtml @35,41 itemLabel=”#{pessoa.etiqueta}”: La clase java.lang.Cadena’ no tiene la propiedad ‘etiqueta’.

Este es mi conversor de clase (solo para probar):

public class ConversorSelectItem implements Converter {

@Override
public Object getAsObject(FacesContext context, UIComponent component, String value) {      
     if (value!=null && value.isEmpty())
         return null;

     SelectItem selectItem=new SelectItem();
     selectItem.setLabel(value);
     return selectItem;     
}

@Override
public String getAsString(FacesContext context, UIComponent component, Object object) {
    return ((SelectItem)object).getLabel();
}
}

Aquí es donde yo trate de usar p:autocompletar:

<p:autoComplete value="#{modeloPopupBuscaPessoa.itemSelecionado}"
            completeMethod="#{controladorSugestaoPessoa.atualizarSugestoes}"
            var="pessoa" itemLabel="#{pessoa.label}" itemValue="#{pessoa.value}"
            converter="#{conversorSelectItem}"/>

Hice algo mal? No hay un defecto convertidor SelectItem? Hay una manera más fácil para implementar este convertidor?

OriginalEl autor brevleq | 2011-10-04

5 respuestas

  1. 12

    Usted no debe alimentar con List<SelectItem>. Usted debe alimentar con List<Pessoa>. Usted también no debe concentrarse en la conversión de SelectItem. Usted debe concentrarse en la conversión del valor del artículo, que es Pessoa. El SelectItem es un residuo de la vieja JSF 1.x las edades. En JSF 2.x esto no es obligatorio ya, gracias a la var, itemValue y itemLabel atributos en la vista. Esto mantiene su frijol limpio de vista específico de desorden.

    La Converter sólo es necesario cada vez que utilice itemValue="#{pessoa}" y la #{modeloPopupBuscaPessoa.itemSelecionado} se refiere a un Pessoa de la propiedad. Usted debe, a continuación, en getAsString() convertir Pessoa a su único String representación (por lo que puede ser impreso en HTML) y en getAsObject() convertir de String a Pessoa (de modo que se pueden establecer en el bean de la propiedad).

    Sin embargo, si #{pessoa.value} es un String y #{modeloPopupBuscaPessoa.itemSelecionado} es también un String, entonces usted debe utilizar itemValue="#{pessoa.value}" y quitar el Converter por completo.

    Véase también:

    Gracias BalusC, ahora funciona bien

    OriginalEl autor BalusC

  2. 6

    Un Conversor genérico que se puede utilizar para Primefaces Auto-completa y todos los otros fines:

    import java.util.Map;
    import java.util.Map.Entry;
    import java.util.UUID;
    import java.util.WeakHashMap;
    
    import javax.faces.component.UIComponent;
    import javax.faces.context.FacesContext;
    import javax.faces.convert.Converter;
    import javax.faces.convert.FacesConverter;
    
    @FacesConverter(value = "entityConverter")
    public class EntityConverter implements Converter {
    
        private static Map<Object, String> entities = new WeakHashMap<Object, String>();
    
        @Override
        public String getAsString(FacesContext context, UIComponent component, Object entity) {
            synchronized (entities) {
                if (!entities.containsKey(entity)) {
                    String uuid = UUID.randomUUID().toString();
                    entities.put(entity, uuid);
                    return uuid;
                } else {
                    return entities.get(entity);
                }
            }
        }
    
        @Override
        public Object getAsObject(FacesContext context, UIComponent component, String uuid) {
            for (Entry<Object, String> entry : entities.entrySet()) {
                if (entry.getValue().equals(uuid)) {
                    return entry.getKey();
                }
            }
            return null;
        }
    
    }
    Hola Makky Gracias por el conversor genérico de código es una buena idea y muy útil. Puedo cambiar de Mapa<Object, String> entidades a la Lista también si quiero a la derecha??
    Sí, por supuesto, usted puede.
    erm, las entidades de mapa podrían llenar más el tiempo? cuando llega limpiado? (=memory hog)
    ¿Qué sugeriría usted para evitar este problema?

    OriginalEl autor Makky

  3. 1

    Uno más sencilla de lograr esto por medio de:

    la invalidación de la toString() método en Pessoa clase Pojo.
    Este método toString () de sólo debe devolver la Etiqueta que desea mostrar.

    Si utiliza este método a continuación hay SIN NECESIDAD de convertidor de.

    Por ejemplo:

    public class Pessoa implements Serializable{
    
    private String value;
    private String label;
    
    //Setter and getters
    
    @Override
    public void toString(){
    return label;
    }
    
    }

    A continuación, puede utilizar:

    <p:autoComplete value="#{modeloPopupBuscaPessoa.itemSelecionado}"
                    completeMethod="#{controladorSugestaoPessoa.atualizarSugestoes}"
                    var="pessoa" itemLabel="#{pessoa}" itemValue="#{pessoa.value}"/>

    Esta es la forma en que actualmente estoy usando y funciona bien.

    Utilizar el convertidor que es una recomendación.
    Convertidor convierte Objeto Cadena a la derecha?? Por defecto en java si un objeto que se necesita para ser mostrada a continuación, JVM invocará al método toString (). Eso es lo que estoy haciendo en toString(). Ambos métodos rendimientos mismo solo resultados. Tanques y seguro que voy a utilizar el Convertidor como se recomienda
    He publicado un conversor genérico que funcionaría para cualquier objeto.

    OriginalEl autor Kishor Prakash

  4. 0

    Me enfrentó el mismo tema y el autor del comentario en Primefaces autocompletar con POJO y Cadena de valor me dio la pista para encontrar el origen del problema en mi caso.

    Resumen

    El problema es que value=#{objectValue} es de tipo String pero el método que se hace referencia en completeMethod está volviendo un List<Object>.

    El Diseño

    Tengo el siguiente POJOs (simplificado):

    public class CollaboratorGroup {
       private String groupId;
    
       private String groupName;
    
       private Collaborator piUserId;
    
       ...
    }

    y

    public class Collaborator {
       private String userId;
    
       private String fullName;
    
       private String groupId;
       ...
    }

    No importa si se trata de un diseño muy útil. Sólo quiero abordar el tema.

    La siguiente p:autoComplete (simplificado):

    <p:autoComplete var="group"
        itemLabel="#{group.groupId}"
        itemValue="#{group.groupId}"
        completeMethod="#{bean.completeGroup}"
        value="#{collaborator.groupId}">
        <f:facet name="itemtip">
            <p:panelGrid columns="2">
                <f:facet name="header">
                    <h:outputText value="#{group.groupId}" />
                </f:facet>
                <h:outputText value="Name:" />
                <h:outputText value="#{group.groupName}" />
                <h:outputText value="PI" />
                <h:outputText value="#{group.piUserId.fullName}" />
            </p:panelGrid>
        </f:facet>
    </p:autoComplete>

    va a tirar The class 'java.lang.String' does not have the property 'groupId'. Cuando me cambio a itemLabel=#{group}, voy a ver el groupId CG00255 en el campo de entrada, pero muchos de [email protected] en la lista desplegable. Si puedo elegir uno de estos, este toString() valor se establece a Colaborador.groupId que no se desea.

    La Fuente del Problema

    Puedo alimentar a la p:autoComplete con un List<CollaboratorGroup> mientras Collaborator.groupId es un String y itemLabel se utiliza para “formato” ambos, el String groupId establecer como value="#{collaborator.groupId}" y la CollaboratorGroup que viene de la List, generados por completeMethod="#{bean.completeGroup}".

    Posibles Soluciones

    1. Puede ajustar el Model cambiando el miembro groupId a CollaboratorGroup en Collaborator si no destruir su diseño. En este caso, especialmente como CollaboratorGroup tiene el miembro Collaborator piUserId.
    2. Sólo podría llenar el p:autoComplete con List<String> groupIdList pero en este caso usted tiene que encontrar una solución diferente para el itemtip.

    3. Una solución muy rápida es utilizar itemLabel="#{group.class.simpleName eq 'String' ? group : group.groupId}" tal y como figura en Primefaces autocompletar con POJO y Cadena de valor.

      • Problemas
        • Usted tiene cuidado sobre NullPointerExceptions.
        • Llenar su View con la lógica.
        • No es muy flexible, dinámico o de diseño.
    4. Implementar 3. en un bean método itemLabel="#{bean.printGroupId(group)}" donde usted tiene control completo sobre la lógica. Esto es lo que hice.

      public String printGroupId(Object group) {
          if (group == null) return null;
          return (group instanceof String) ? (String) group : (group instanceof CollaboratorGroup) ? ((CollaboratorGroup) group).getGroupId() : null;
      }

      (No el mejor, sólo para darles una idea.)

    OriginalEl autor Robster

  5. -1
     ELContext elContext = FacesContext.getCurrentInstance().getELContext();
     ItemBean itemBean = (ItemBean) elContext.getELResolver().getValue(elContext, null, "itemBean");
     for(Item item : itemBean.getItems()){
         if(item.getId().getItemCode().equals(value)){
             return item;
         }
     }
    en Conver Clase ,Objeto Público getAsObject(FacesContext contexto, UIComponent componente de la Cadena de valor) { este método de escribir la lógica anterior y obtener la lista de elementos de frijol ,sin duda, lo va a conseguir
    Por favor agregue esto a su respuesta, usted puede editar. Y por favor, añadir un poco más de explicación acerca de por qué esto funciona y es una respuesta mejor de lo que ya está publicado

    OriginalEl autor Esk Srikanth

Deja un comentario

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *