2017-12-06 7 views
1

h:selectOneMenuのコンバーターを1つのBeanで使用して実装しましたが、同じコンバーターを別のBeanから作成する代わりに、別のBeanから同じコンバータを使用します。異なるBeanに対して同じコンバータを作成しないようにする

現在私が持っている:

コンバータ

@FacesConverter(value = "csiConverter") 
public class CsiConverter implements Converter { 

@Override 
public Object getAsObject(FacesContext ctx, UIComponent uiComponent, String dcId) { 
    ValueExpression vex = 
      ctx.getApplication().getExpressionFactory() 
        .createValueExpression(ctx.getELContext(), 
          "#{cfgbean}", CfgDbBean.class); 

    ... 
} 

@Override 
public String getAsString(FacesContext facesContext, UIComponent uiComponent, Object o) { 
    return ((Csi) o).getCsi(); 
} 

とXHTML

 <div class="form-group"> 
     <label>CSI</label> 
    <h:selectOneMenu id="csi" styleClass="form-control" value="#{cfgbean.csi}" converter="csiConverter"> 
      <f:selectItems var="csival" itemLabel="#{csival.csi} - #{csival.name}" itemValue="${csival}" value="#{cfgbean.csilist}" /> 
     </h:selectOneMenu>   
     </div> 

これは、すべて正常に動作しています。 ここでは、別のxhtmlに同じselectOneMenuを作成して、同じ目的で同じコンテンツを表示するために別のBeanに連絡したいと考えています。

問題は、Converterクラス内のBean参照およびBeanクラスをケーブルで接続されていることである。(createValueExpression(ctx.getELContext(), "#{cfgbean}", CfgDbBean.class);

そのリファレンスケーブルに回避し、すべてのBeanのための一般的なcsiConverterを持つことができますどのように?

おかげ

+1

[JSF 2のカスタムコンバータの引数付きのカスタムコンバータ]の可能な複製(https://stackoverflow.com/questions/11613134/custom-converter-in-jsf-2-with-arguments) –

+0

返信いただきありがとうございます。専用のBeanを作成して他のすべてのBeanを参照するには、読みやすいものを実装する方が簡単だと思います。 私は後で共有し、コメントします。 –

+0

私はしようとしたが動作していない。オブジェクトを別のBeanから取得するには、getasobjectメソッドにチェックを追加する必要があります。 –

答えて

0

これはジャスパーの助けを借りて行われる部分である:あなたの豆は抽象Beanを拡張する場合は/、あなたのようなBeanを取得することができますすることができます(任意の名前、あなたがそれを与えたか)CsiHolderのようなインターフェイスを実装しています。

ValueExpression valueExpression = uiComponent.getValueExpression("value"); 
    String beanName = valueExpression.getExpressionString(); 
    //#{formbean.data} 
    if(beanName.contains("#{")){ 
     String[] output = beanName.split("\\{"); 
     if(output.length!=2){ 
      throw new IllegalArgumentException(beanName + " - invalid format!"); 
     }else{ 
      if(output[1].contains(".")){ 
       String[] bean = output[1].split("\\."); 
       beanName = bean[0]; 
      }else{ 
       throw new IllegalArgumentException(output[1] + " - invalid format!"); 
      } 
     } 
    }else{ 
     throw new IllegalArgumentException(beanName + " - invalid format!"); 
    } 

    Object p = ctx.getApplication().evaluateExpressionGet(ctx, "#{"+beanName+"}", Object.class); 

    if(p instanceof FormBean){ 
     FormBean p2 = (FormBean) p; 
     return p2.getName(dcId); 
    } 
    ... 
    ... 
    ... 

問題は解決しており、問題は解決しました。

0

私はgetAsObject方法は、必要に応じてBean名を渡すために属性を使用して変換器を有しています。私は、Bean名を決定することができますタイプから

ValueExpression valueExpression = uiComponent.getValueExpression("value"); 
Class<?> type = valueExpression.getType(ctx.getELContext()); 

:属性が設定されていない場合、私は、オブジェクトの種類値がバインドされているを検出するために、コンポーネントのvalue属性を使用します。これはあなたのためのオプションかもしれません。私の場合は

String beanName = type.getSimpleName() + "Bean"; 
beanName = beanName.substring(0, 1).toLowerCase() + 
      beanName.substring(1); 

違う豆の同じタイプを使用している場合は、あなたからBean名を得ることができる必要があります:

valueExpression.getExpressionString() 

それが使用された元の文字列を返します。変更されていない表現を作成する。あなたの場合:

#{cfgbean.csi} 

その文字列から.csi部分を削除して、そのBeanを取得してください。

ctx.getApplication().evaluateExpressionGet(ctx, "#{cfgbean}", CsiHolder.class) 
+0

これを実装する方法について、より多くの情報を共有できますか?ありがとう –

+0

..しかし、私はあなたが別の豆で同じタイプを使用していると思いますか? –

+0

はい、別の豆が同じ時間を使用しています。提案通り私は FormAdd.xhtml @ 162,154 value = "#{formbean.csi}" を取得します。この値の文字列を解析してBeanの名前を取得し、Javaクラスをマッピングした後に、正しいでしょうか? –

関連する問題