以下のように記述した場合、value値はLoginというBackingBeanのuserIDに設定される。
<h:inputText value=”#{Login.userID}” required=”true” >
このような記述方法をValueBindingという。この場合は値を設定しているように見えるが、逆にBackingBeanの持っている値をvalueに設定したい場合もある。
カスタムタグでValueBindingを利用したい場合は、ValueBindingのための処理を実装しなければならない。
サンプル
タグクラス
まずはタグクラスを改良する。
setPropertiesメソッドの中でしている「属性値設定処理」部分を変更する。
/**
* タグに設定された属性を設定します。
*/
protected void setProperties(UIComponent component) {
super.setProperties(component);
UIFieldset fieldset = (UIFieldset)component;
if(this.style != null){
if(isValueReference(style)){
ValueBinding bind =
FacesContext.getCurrentInstance().getApplication().createValueBinding(style);
fieldset.setValueBinding("style", bind);
}else{
fieldset.getAttributes().put("style", this.style);
}
}
}
- 属性値が設定されている場合にのみこれらの処理は実行すればいい。
- isValueReferenceメソッドによってValueBindingしているのかどうかを判定
- ValueBindingならばValueBindingクラスに値を設定する。
- ValueBindingではないならば属性をコンポーネントに設定する。
Renderer
RendererでもValueBindingを使うかどうかの判定を実装する。
/**
* 開始タグを出力します。
*/
public void encodeBegin(FacesContext context, UIComponent component)
throws IOException {
ResponseWriter writer = context.getResponseWriter();
UIFieldset fieldset = (UIFieldset)component;
String style = (String)fieldset.getAttributes().get("style");
if(style == null){
System.out.println("FieldsetRenderer.encodeBegin:bind check");
ValueBinding bind = fieldset.getValueBinding("style");
if(bind != null){
style = (String)bind.getValue(context);
}
}
System.out.println("FieldsetRenderer.encodeBegin:style=" + style);
writer.startElement("fieldset", component);
if(style != null){
writer.writeAttribute("class", style, null);
}
}
- 属性値がない場合はValueBindingなのかどうかを判定する。
- 属性値名のValueBindingがnullではないならその値を取得する。
- それでも属性値がない場合(null)はwriteAttributeはできない(NullPonterException)ので回避しなければならない。