2010-12-14 6 views
0

J'ai un problème avec les valeurs des attributs d'un composant validateur. Apparemment, le validateur est créé lorsque je visite une page pour la première fois.Actualiser JSF validateur attributs sur rerender

S'il vous plaît voir mon code ci-dessous:

<h:inputText value="#{qsetting.value}" rendered="#{qsetting.dataType=='Double'}"> 
    <mw:validateRange min="#{qsetting.minValue}" max="#{qsetting.maxValue}" /> 
</h:inputText> 

Le composant est inputText par ajax, mais nouveau rendu apparemment, y compris la valeur affichée. Malheureusement, les valeurs qsetting.minValue et qsetting.maxValue ne sont pas actualisées, ce qui empêche mon validateur de fonctionner correctement.

Est-il possible de rafraîchir le validateur, pour vous assurer qu'il re-récupère ses attributs ou simplement créer une nouvelle instance de validateur? La classe de validateur elle-même est en train de mettre en œuvre "Validator, Serializable". En outre, j'utilise jsf1.2 avec facelets ...

Merci, Steven

+0

Il serait utile si vous avez marqué la 'mw'.Je n'ai aucune idée de ce que c'est. Est-ce un composant personnalisé peut-être? –

+0

Oui, c'est un validateur personnalisé. Rien de spécial là-dedans cependant, seulement 2 variables Double membre, à la fois avec un getter et un setter. Le problème est que les getters ne sont appelés que lorsque la page est construite. Donc, lors du redéclenchement, l'arborescence des composants existe et les setters du validateur ne sont pas appelés. Par conséquent, j'ai des valeurs incorrectes dans mon validateur, et je veux corriger cela en quelque sorte ... (n'a pas testé, mais je crois que vous obtiendriez les mêmes résultats avec une balise f: valiateLongRange) –

Répondre

0

J'ai frappé ce problème dans un environnement non-ajax quelques fois au cours des années, et il frappe à nouveau aujourd'hui. L'ajout d'Ajax ne change rien car un attribut validateur n'est jamais réévalué une fois la page créée, ajax ou autre.

La seule solution que je suis venu avec est de définir l'attribut validateur à une expression de validateur, puis d'évaluer cette expression dans la méthode de validation.

Un autre problème que je frappe (aussi avec JSF 1.2 et Facelets) est que toutes les variables EL travaillé. J'ai dû utiliser un bean géré statique comme racine de mon expression pour accéder à la valeur. Un facelet ui: la valeur de param comme racine ne fonctionnerait pas. Je n'ai pas testé pour voir ce que d'autres peuvent ne pas évaluer correctement. Cela pourrait être dû à un autre bug dans la conception de JSF lui-même. Voir http://myfaces.apache.org/core12/myfaces-api/apidocs/javax/faces/context/FacesContext.html#getELContext%28%29.

Par exemple, au lieu de:

max="#{qsetting.maxValue}" 

utilisation

maxExpression="qsetting.maxValue" 

Puis

public String getMax(FacesContext context) { 
    Application app = context.getApplication(); 
    ExpressionFactory exprFactory = app.getExpressionFactory(); 
    ValueExpression ve = exprFactory.createValueExpression(context.getELContext(), 
      "#{" + getMaxExpression() + "}", 
      String.class); 

    Object result = ve.getValue(context.getELContext()); 

    return (String)result; 
} 

public String getMaxExpression() { 
    return this.maxExpression; 
} 

public void setMaxExpression(String maxExpression) { 
    this.maxExpression = maxExpression; 
} 


//// StateHolder 

public boolean isTransient() { 
    return isTransient; 
} 

public void setTransient(boolean newTransientValue) { 
    isTransient = newTransientValue; 
} 

public Object saveState(FacesContext context) { 
    Object[] state = new Object[1]; 
    state[0] = maxExpression; 
    return state; 
} 

public void restoreState(FacesContext context, Object state) { 
    Object[] values = (Object[]) state; 
    maxExpression = (String) values[0]; 
} 

MISE À JOUR 2012-09-19:

Après avoir enquêté sur la façon dont MyFaces Commons résoud ce problème, la meilleure solution consiste à modifier les règles utilisées par Facelets pour évaluer les expressions d'attribut de validateur et de convertisseur.

Il se résume à l'ajout d'une nouvelle métarègle validateur ou convertisseur qui, lorsqu'il est appliqué, vérifie si la valeur d'attribut est non littéral. S'il n'est pas littéral, appelez une méthode spéciale sur votre validateur ou convertisseur qui transmet l'expression de valeur plutôt que la valeur actuelle.

http://svn.apache.org/viewvc/myfaces/commons/trunk/myfaces-commons-validators/src/main/java/org/apache/myfaces/commons/validator/_ValidatorRule.java?view=markup

Le validateur à ce moment-là a besoin de stocker l'expression de valeur que l'état et l'évaluer en cas de besoin. MyFaces commons fournit toute l'infrastructure compliquée pour que cela se produise de manière générique, mais vous pouvez vider tout cela et écrire une règle personnalisée simple et gérer directement la ValueExpression vous-même, similaire à ce que j'ai posté à l'origine.

Questions connexes