2011-09-23 10 views
10

私は、カスタムISO日時Converter作成しました:データテーブルの各行に対してコンバータプロパティを設定するにはどうすればよいですか?

public class IsoDateTimeConverter implements Converter, StateHolder { 

    private Class type; 
    private String pattern; 

    private boolean transientValue = false; 

    public void setType(Class type) { 
     this.type = type; 
    } 

    public void setPattern(String pattern) { 
     this.pattern = pattern; 
    } 

    @Override 
    public Object getAsObject(FacesContext context, UIComponent component, String value) throws ConverterException { 
     if (StringCheck.isNullOrEmpty(value)) { 
      throw new ConverterException("value not specified"); 
     } 

     try { 
      if (IsoDate.class.equals(type)) { 

       if (WebConst.ISO_DATE_NONE.equals(value)) { 
        return IsoDate.DUMMY; 
       } else { 
        //TODO User spezifische TimeZone auslesen 
        return new IsoDate(value, TimeZone.getDefault().getID()); 
       } 

      } else if (IsoTime.class.equals(type)) { 

       if (WebConst.ISO_TIME_NONE.equals(value)) { 
        return IsoTime.DUMMY; 
       } else { 
        //TODO User spezifische TimeZone auslesen 
        return new IsoTime(value, TimeZone.getDefault().getID()); 
       } 

      } else if (IsoTimestamp.class.equals(type)) { 

       if (WebConst.ISO_TIMESTAMP_NONE.equals(value)) { 
        return IsoTimestamp.DUMMY; 
       } else { 
        //TODO User spezifische TimeZone auslesen 
        return new IsoTimestamp(value, TimeZone.getDefault().getID()); 
       } 

      } else { 
       throw new ConverterException("value not convertible"); 
      } 
     } catch (Exception e) { 
      throw new ConverterException(e.getMessage()); 
     } 
    } 

    @Override 
    public String getAsString(FacesContext context, UIComponent component, Object value) throws ConverterException { 
     if (value == null) { 
      throw new ConverterException("value not specified"); 
     } 

     if (IsoDate.class.equals(value)) { 
      IsoDate isoDate = (IsoDate) value; 

      if (isoDate.isDummy()) { 
       return WebConst.ISO_DATE_NONE; 
      } else { 
       //TODO User spezifische TimeZone auslesen 
       return isoDate.toString(pattern, TimeZone.getDefault().getID(), false); 
      } 

     } else if (IsoTime.class.equals(value)) { 
      IsoTime isoTime = (IsoTime) value; 

      if (isoTime.isDummy()) { 
       return WebConst.ISO_TIME_NONE; 
      } else { 
       //TODO User spezifische TimeZone auslesen 
       return isoTime.toString(pattern, TimeZone.getDefault().getID(), false); 
      } 

     } else if (IsoTimestamp.class.equals(value)) { 
      IsoTimestamp isoTimestamp = (IsoTimestamp) value; 

      if (isoTimestamp.isDummy()) { 
       return WebConst.ISO_TIMESTAMP_NONE; 
      } else { 
       //TODO User spezifische TimeZone auslesen 
       return isoTimestamp.toString(pattern, TimeZone.getDefault().getID(), false); 
      } 

     } else { 
      throw new ConverterException("value not convertible"); 
     } 
    } 

    @Override 
    public Object saveState(FacesContext context) { 
     return new Object[]{type, pattern}; 
    } 

    @Override 
    public void restoreState(FacesContext context, Object state) { 
     type = (Class) ((Object[]) state)[0]; 
     pattern = (String) ((Object[]) state)[1]; 
    } 

    @Override 
    public boolean isTransient() { 
     return transientValue; 
    } 

    @Override 
    public void setTransient(boolean transientValue) { 
     this.transientValue = transientValue; 
    } 
} 

をそして、私は次のビューに<mh:IsoDateTimeConverter>としてConverterを使用します。

<p:dataTable value="#{imports.list}" var="item"> 
    <p:column> 
     <h:outputText value="#{item.balanceDate}" immediate="true"> 
      <mh:IsoDateTimeConverter type="#{webConst.ISO_DATE_CLASS}" pattern="#{webConst.ISO_DATE_FORMAT}"/> 
     </h:outputText> 
    </p:column> 
</p:dataTable> 

問題は、私が最初にこのビューを開くと、すべてのプロパティは私のConverterクラスに一度だけ設定され、その後、データテーブルは初期プロパティに基づいて値をレンダリングし変換します。

プロパティがローごとに設定されていると予想しました。どうすればこれを達成できますか?

答えて

24

これまで、データテーブルの行がレンダリングされるたびにコンバータのプロパティが設定されることが予想されていました。これは確かに真実ではありません。 JSFは、ビューの作成時にコンポーネントごとに1つのコンバータ・インスタンスを作成しますが、行がレンダリングされるたびにコンバータを作成またはリセットしません。

動作させるにはいくつかの方法があります。

  • 部品の<f:attribute>として動的属性をパスし、その上Converterインターセプトしてみましょう。ここで例を見つけることができます:JSF convertDateTime with timezone in datatable。これは、代わりにConverterのEL関数を使用

    <h:outputText value="#{item.balanceDate}"> 
        <f:converter converterId="isoDateTimeConverter" /> 
        <f:attribute name="pattern" value="#{item.pattern}" /> 
    </h:outputText> 
    

  • として使用することができます。ここに例があります:Facelets and JSTL (Converting a Date to a String for use in a field)。これは、その後、使用することができます


  • <h:outputText value="#{mh:convertIsoDate(item.balanceDate, item.pattern)}" /> 
    

    としてバインドコンバータとのDataTableのDataModel同じ管理対象Beanのプロパティとして。これにより、行データに基づいてコンバータのプロパティを返す前に設定することができます。ここで(それはあなたのカスタムコンバータPrimeFacesコンポーネント上とで同様に良好な動作するはずです)標準JSFコンポーネントと標準DateTimeConverterに基づいて基本的なキックオフの例です:

    <h:dataTable value="#{bean.model}" var="item"> 
        <h:column> 
         <h:outputText value="#{item.date}" converter="#{bean.converter}" /> 
        </h:column> 
    </h:dataTable> 
    

    @ManagedBean 
    @ViewScoped 
    public class Bean implements Serializable { 
    
        private List<Item> items; 
        private DataModel<Item> model; 
        private DateTimeConverter converter; 
    
        @PostConstruct 
        public void init() { 
         items = Arrays.asList(
          new Item(new Date(), "dd-MM-yyyy"), 
          new Item(new Date(), "yyyy-MM-dd"), 
          new Item(new Date(), "MM/dd/yyyy")); 
         model = new ListDataModel<Item>(items); 
         converter = new DateTimeConverter(); 
        } 
    
        public DataModel<Item> getModel() { 
         return model; 
        } 
    
        public Converter getConverter() { 
         converter.setPattern(model.getRowData().getPattern()); 
         return converter; 
        } 
    
    } 
    

    で(Itemクラスがありますこれは

    もたらす二つの特性Date dateString pattern

    とだけ豆OmniFaces<o:converter>代わりに、2011年9月23日


  • 使用
    2011-09-23

    23-09-。これは、属性のELのレンダリング時間評価をサポートします。 the <o:converter> showcase exampleも参照してください。

    <h:outputText value="#{item.balanceDate}"> 
        <o:converter converterId="isoDateTimeConverter" pattern="#{item.pattern}" /> 
    </h:outputText> 
    
関連する問題