2012-04-25 6 views

Respuesta

43

Se podría comparar Class#getName() o, tal vez mejor, Class#getSimpleName() a un String.

<h:link rendered="#{model['class'].simpleName eq 'ClassA'}">  
    #{errorMessage1} 
</h:link> 
<h:link rendered="#{model['class'].simpleName eq 'ClassB'}">  
    #{errorMessage2} 
</h:link> 

nota la importancia de especificar Object#getClass() con la paréntesis de la notación ['class'] porque class se reservó un literal de Java que de otro modo una excepción en EL EL 2.2+.

La alternativa segura de tipo es agregar algo de public enum Type { A, B } junto con public abstract Type getType() a la clase de base común del modelo.

<h:link rendered="#{model.type eq 'A'}">  
    #{errorMessage1} 
</h:link> 
<h:link rendered="#{model.type eq 'B'}">  
    #{errorMessage2} 
</h:link> 

Cualquier valor no válido arrojaría aquí una excepción EL durante el tiempo de ejecución en EL 2.2+.

+0

no funcionaría para interfaces ... ¿alguna sugerencia para eso? – Lucas

+0

@Lucas: es imposible si la implementación es una interfaz :) Si tiene un problema, es causado por otra cosa. – BalusC

+0

La sugerencia de prueba de cadena de clases es útil en algunas situaciones, pero no funciona para interfaces o subclases. Existe una necesidad real y urgente de instanceof. Por favor vote aquí: http://java.net/jira/browse/JSP_SPEC_PUBLIC-113. Véase también el problema relacionado, cómo llamar a un componente compuesto vinculado a un tipo solo para un tipo coincidente utilizando algún tipo de prueba que no sea 'renderizado', que no parece funcionar durante la fase de construcción (observaciones en la parte inferior de http: // stackoverflow. com/questions/16665705/jsf-how-prevent-stackoverflow-due-to-recursion-during-build-phase-despite-rend) –

7

Eso no funciona en EL. Utilizar el bean de respaldo para esto:

public class MyBean { 

    public boolean getIsClassA() { 
     if(model instanceof ClassA) { 
      return true; 
     } 
     return false; 
    } 


} 

y luego hacer el cheque llamando al bean de respaldo:

<h:link outcome="#{PageNameA}?faces-redirect=true&amp;" rendered="#{myBean.isClassA}">  
    #{errorMessage} 
</h:link> 

+0

Este es de hecho una buena respuesta. Adopté otra solución: rendered = "# {listRow.rowData.getClass(). GetName() == 'ClassB'}" (ClassB debe estar completamente quelificada). ¿Hay algo fuerte en contra de esta solución "no tan elegante"? – Francesco

+1

Creo que esta solución es mejor porque es más fácil de entender, pero eso depende en cierta medida de la intención. Si su intención es mostrar solo un enlace u otro, coloque solo un enlace en la vista y use un bean de respaldo para la _ lógica de negocios_ que decida cuál debe ser el resultado. Esto también es más comprobable. Si desea mostrar posiblemente ambos enlaces, entonces la otra solución funciona bien, pero aún así preferiría el bean de respaldo para la capacidad de prueba y la claridad. Tienes un lenguaje perfectamente bueno (java) así que no hay necesidad de hacer cosas locas y nombres de clase de código en EL. – Brian

+0

Esta es una solución más general que la prueba de Cadena de Clase basada en EL (a veces todavía útil) sugerida por BalusC, ya que puede funcionar para interfaces y subclases, pero es doloroso tener que hacerlo todo el tiempo, y a menudo contamina ambos los respaldos y/o entidades (o donde sea que uno coloque la prueba). Necesitamos instanceof en JSF2.x a.s.a.p! –

2

Hay una manera, ver

JSF EL: instanceof reserved but not yet implemented?

Sin embargo, el operador instanceof todavía no se aplica, al menos en Mojarra 2.1. Vote por el fallo aquí:

http://java.net/jira/browse/JSP_SPEC_PUBLIC-113

La mejor solución actualmente es probablemente para almacenar el nombre de la clase en un bean de respaldo getter en lugar de crear un método de prueba booleana para cada clase:

public String getSelectedNodeClassName() 
{ 
    return selectedNode.getClass().getSimpleName(); 
} 

Entonces sería una mezcla de las soluciones de BalusC y flash. Sin embargo, sería mucho más fácil de leer en JSF que BalusC de más se asemeja más o menos la futura utilización instanceof operador:

rendered="#{nodeManager.selectedNodeClassName eq 'ChapterNode'}" 

Esto no va a producir un método de ensayo en la clase bean de respaldo como flash sugirió. Sin embargo, esto podría ser más lento que flash.

4

funciona:

rendered="#{node.getClass().getSimpleName() == 'Logt_anno'}" 
2

definir una función estática como:

public boolean isInstanceOf(Object obj, Class targetClass) { 
     return targetClass.isInstance(obj); 
    } 

Definir una función EL personalizado para ello, y usar eso. También podríamos pasar un nombre de cadena y hacer un forName() dentro del método.

0

No es muy elegante ya que mezcla JSP EL y la sintaxis de la expresión anterior , pero no requiere ningún extra Java código:

<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%> 

<c:set var="interfaceClass" value="<%=com.example.ClassA.class%>"/> 
<c:set var="implementationClass" value="${model['class']}"/> 
<c:if test="${interfaceClass.isAssignableFrom(implementationClass)}"> 
    <%-- Your logic here. --%> 
</c:if> 
Cuestiones relacionadas