servletcontainerが最小のServlet 3.0 / EL 2.2をサポートしている場合は、UICommand
コンポーネントまたはAjaxBehavior
タグのアクション/リスナーメソッドの引数としてそれを渡します。例えば
<h:commandLink action="#{bean.insert(item.id)}" value="insert" />
と組み合わせて:
public void insert(Long id) {
// ...
}
これは、データモデルがフォーム送信リクエストのために保存されていることのみを必要とします。最善の方法は、Beanをビュースコープに配置することです。@ViewScoped
。
アイテムオブジェクト全体を渡すこともできます。
<h:commandLink action="#{bean.insert(item)}" value="insert" />
と:
public void insert(Item item) {
// ...
}
サーブレット2.5コンテナでは、JBoss ELのように、これをサポートするEL実装を提供する場合も可能です。構成の詳細については、この回答を参照してください。
コンポーネントで使用<f:param>
しUICommand
ます。リクエストパラメータを追加します。
<h:commandLink action="#{bean.insert}" value="insert">
<f:param name="id" value="#{item.id}" />
</h:commandLink>
Beanがリクエストスコープの場合、JSFに設定させます @ManagedProperty
@ManagedProperty(value="#{param.id}")
private Long id; // +setter
または、Beanのスコープがより広い場合、またはより詳細な検証/変換が必要な場合<f:viewParam>
は、ターゲットビューで使用します。f:viewParamと@ManagedPropertyも参照してください。
<f:viewParam name="id" value="#{bean.id}" required="true" />
どちらの方法でも、フォーム送信のためにデータモデルを必ずしも保持する必要がないという利点があります(Beanがリクエストスコープの場合)。
コンポーネントで使用<f:setPropertyActionListener>
しUICommand
ます。利点は、Beanのスコープがリクエストスコープよりも広い場合に、リクエストパラメータマップにアクセスする必要がなくなることです。
<h:commandLink action="#{bean.insert}" value="insert">
<f:setPropertyActionListener target="#{bean.id}" value="#{item.id}" />
</h:commandLink>
と組み合わせて
private Long id; // +setter
id
アクションメソッドのプロパティでのみ使用できます。これは、データモデルがフォーム送信リクエストのために保存されていることのみを必要とします。最善の方法は、によってBeanをビュースコープに配置すること@ViewScoped
です。
DataModel<E>
代わりにdatatable値をバインドし、次にアイテムをラップします。
<h:dataTable value="#{bean.model}" var="item">
と
private transient DataModel<Item> model;
public DataModel<Item> getModel() {
if (model == null) {
model = new ListDataModel<Item>(items);
}
return model;
}
(を実装しtransient
てDataModel
いないため、ビューまたはセッションスコープBeanでこれを使用している場合、それを作成し、ゲッターで遅延してインスタンス化することが必須ですSerializable
)
その後、DataModel#getRowData()
何も渡さずに現在の行にアクセスできます(JSFは、クリックされたコマンドリンク/ボタンのリクエストパラメータ名に基づいて行を決定します)。
public void insert() {
Item item = model.getRowData();
Long id = item.getId();
// ...
}
これには、フォーム送信リクエストのためにデータモデルが保持されることも必要です。最善の方法は、によってBeanをビュースコープに配置すること@ViewScoped
です。
Application#evaluateExpressionGet()
プログラムで現在のを評価するために使用します#{item}
。
public void insert() {
FacesContext context = FacesContext.getCurrentInstance();
Item item = context.getApplication().evaluateExpressionGet(context, "#{item}", Item.class);
Long id = item.getId();
// ...
}
どちらを選択するかは、機能要件と、どちらが他の目的に対してより多くの利点を提供するかによって異なります。私は個人的には#1に進むか、サーブレット2.5コンテナーもサポートする場合は#2に進みます。