JSF 2.X がそのように動作する方法と理由を理解するために、単純なコンポーネントを構築しようとしています。私は新しい注釈を使用しており、明確な例をまとめようとしています。
したがって、コンポーネントをビルドし、次のように xhtml ファイルにデプロイしました。
<kal:day value="K.Day" title="Kalendar" model="#{kalendarDay}"/>
UIComponent 内で次のことを行います。
ValueExpression ve = getValueExpression("model");
if (ve != null)
{
System.out.println("model expression "+ve.getExpressionString());
model = (KalendarDay) ve.getValue(getFacesContext().getELContext());
System.out.println("model "+model);
}
「#{kalendarDay}」という式が正しく表示され、ページとコンポーネントの間で値が正常に送信されたことを示します。ただし、式の評価は「null」になります。
これは、この時点でバッキング Bean が使用できないことを示しているようですが、ページは正しく検証およびデプロイされます。したがって、Bean が実行時にそこにあることは 95% 確実です。
おそらくこれはフェーズの問題ですか?レンダラーのデコードでこれを評価し、属性マップに値を設定する必要がありますか? 実際の値と値式の組み合わせについては、まだ少し混乱しています。
したがって、私の質問は、モデルの valueExpression をどこで取得して評価する必要があり、評価の結果を UIComponent に保存する必要があるのか、それとも毎回評価する必要があるのかということです。
以下のSSCCEファイルは、問題を実証するために必要な唯一のファイルだと思います
Bean インターフェース -----
/**
*
*/
package com.istana.kalendar.fixture;
import java.util.Date;
/**
* @author User
*
*/
public interface KalendarDay
{
public Date getDate();
}
ビーン実装 ---
/**
*
*/
package com.istana.kalendar.session.wui;
import java.util.Calendar;
import java.util.Date;
import javax.ejb.Stateful;
import javax.inject.Named;
import com.istana.kalendar.fixture.KalendarDay;
/**
* @author User
*
*/
@Named ("kalendarDay")
@Stateful
public class KalKalendarDay
implements KalendarDay
{
private Calendar m_date = Calendar.getInstance();
/* (non-Javadoc)
* @see com.istana.kalendar.fixture.KalendarDay#getDate()
*/
@Override
public Date getDate()
{
return m_date.getTime();
}
}
UI コンポーネント ---
/**
*
*/
package com.istana.kalendar.fixture.jsf;
import javax.el.ValueExpression;
import javax.faces.component.FacesComponent;
import javax.faces.component.UIOutput;
import com.istana.kalendar.fixture.KalendarDay;
/**
* @author User
*
*/
@FacesComponent (value=UIDay.COMPONENT_TYPE)
public class UIDay extends UIOutput
{
static final
public String COMPONENT_TYPE = "com.istana.kalendar.fixture.jsf.Day";
static final
public String COMPONENT_FAMILY = "com.istana.kalendar.fixture.jsf.Day";
private KalendarDay m_model;
private String m_title;
@Override
public String getRendererType()
{
return UIDayRenderer.RENDERER_TYPE;
}
@Override
public String getFamily()
{
return COMPONENT_FAMILY;
}
public KalendarDay getModel()
{
KalendarDay model = (KalendarDay) getStateHelper().eval("model");
System.out.println("model "+model);
return model;
}
public void setModel(KalendarDay model)
{
getStateHelper().put("model",model);
}
public String getTitle()
{
return (String) getStateHelper().eval("title");
}
public void setTitle(String title)
{
getStateHelper().put("title",title);
}
}
UIComponentRenderer ---
/**
*
*/
package com.istana.kalendar.fixture.jsf;
import java.io.IOException;
import javax.el.ValueExpression;
import javax.faces.component.UIComponent;
import javax.faces.context.FacesContext;
import javax.faces.context.ResponseWriter;
import javax.faces.render.FacesRenderer;
import javax.faces.render.Renderer;
import com.istana.kalendar.fixture.KalendarDay;
/**
* @author User
*
*/
@FacesRenderer (componentFamily = UIDay.COMPONENT_FAMILY
,rendererType = UIDayRenderer.RENDERER_TYPE
)
public class UIDayRenderer extends Renderer
{
static final
public String RENDERER_TYPE = "com.istana.kalendar.fixture.jsf.DayRenderer";
@Override
public void encodeBegin (FacesContext context,UIComponent component)
throws IOException
{
UIDay uic = (UIDay) component;
ResponseWriter writer = context.getResponseWriter();
writer.startElement("p", uic);
/*
* This is the call that triggers the println
*/
writer.write("Day - "+uic.getModel().getDate());
}
@Override
public void encodeEnd (FacesContext context,UIComponent component)
throws IOException
{
ResponseWriter writer = context.getResponseWriter();
writer.endElement("p");
writer.flush();
}
}
kalendar.taglib.xml ---
<facelet-taglib
id="kalendar"
xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-facelettaglibrary_2_0.xsd"
version="2.0"
>
<namespace>http://istana.com/kalendar</namespace>
<tag>
<tag-name>day</tag-name>
<component>
<component-type>com.istana.kalendar.fixture.jsf.Day</component-type>
</component>
</tag>
</facelet-taglib>