如何将选定的行传递到 dataTable 或 ui:repeat 内的 commandLink?
我在 JSF 2 应用程序中使用 Primefaces。我有一个
,我希望用户能够直接对各个行执行各种操作,而不是选择行。为此,我在最后一列中有几个
。
我的问题:如何将行 ID 传递给命令链接启动的操作,以便我知道要对哪一行进行操作?我尝试使用
:
<p:dataTable value="#{bean.items}" var="item">
...
<p:column>
<p:commandLink actionListener="#{bean.insert}" value="insert">
<f:attribute name="id" value="#{item.id}" />
</p:commandLink>
</p:column>
</p:dataTable>
但它总是产生 0 - 显然,在渲染属性时,行变量 f
不可用(当我使用固定值)。
有人有替代解决方案吗?
I'm using Primefaces in a JSF 2 application. I have a <p:dataTable>
, and instead of selecting rows, I want the user to be able to directly execute various actions on individual rows. For that, I have several <p:commandLink>
s in the last column.
My problem: how can I pass a row ID to the action started by the command link so that I know which row to act on? I tried using an <f:attribute>
:
<p:dataTable value="#{bean.items}" var="item">
...
<p:column>
<p:commandLink actionListener="#{bean.insert}" value="insert">
<f:attribute name="id" value="#{item.id}" />
</p:commandLink>
</p:column>
</p:dataTable>
But it always yields 0 - apparently the row variable f
is not available when the attribute is rendered (it works when I use a fixed value).
Anyone has an alternative solution?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
至于原因,
特定于组件本身(在视图构建时间期间填充),而不是迭代行(在视图渲染时间期间填充)。有多种方法可以实现该要求。
如果您的 servlet 容器至少支持 Servlet 3.0 / EL 2.2,则只需将其作为
UICommand
组件或AjaxBehavior
标记的操作/侦听器方法的参数传递即可。例如结合:
这只需要为表单提交请求保留数据模型。最好的办法是通过
@ViewScoped
将bean放入视图范围内。您甚至可以传递整个项目对象:
与:
在 Servlet 2.5 容器上,如果您提供支持此功能的 EL 实现(例如 JBoss EL),这也是可能的。有关配置详细信息,请参阅此答案。
<小时>
使用
在UICommand
组件中。它添加了一个请求参数。如果您的 bean 是请求范围的,请让 JSF 通过
@ManagedProperty
或者,如果您的 bean 范围更广,或者您想要更细粒度的验证/转换,请使用
在目标视图上,另请参阅 f:viewParam 与 @ManagedProperty:无论哪种方式,这都有一个优点,即不必为表单提交保留数据模型(对于您的 bean 属于请求范围的情况)。
<小时>
使用
在UICommand
组件中。优点是,当 bean 的范围比请求范围更广时,这就不需要访问请求参数映射。结合
它只能通过操作方法中的属性
id
使用。这只需要为表单提交请求保留数据模型。最好的办法是通过@ViewScoped
将bean放入视图范围内。<小时>
将数据表值绑定到
DataModel< ;E>
相反,它依次包装项目。与
(当您在视图或会话作用域 bean 上使用它时,必须使其
暂时
并在 getter 中延迟实例化它,因为DataModel
不会” t 实现可序列化
)然后您将能够通过
DataModel#getRowData()
不传递任何内容(JSF 根据单击的命令链接/按钮的请求参数名称确定行)。这还要求为表单提交请求保留数据模型。最好的办法是通过
@ViewScoped
将bean放入视图范围内。<小时>
使用
Application#evaluateExpressionGet()
以编程方式评估当前的#{item}
。<小时>
选择哪种方式取决于功能要求以及其中一种或另一种是否为其他目的提供了更多优势。我个人会继续使用#1,或者当您也想支持 servlet 2.5 容器时,使用#2。
As to the cause, the
<f:attribute>
is specific to the component itself (populated during view build time), not to the iterated row (populated during view render time).There are several ways to achieve the requirement.
If your servletcontainer supports a minimum of Servlet 3.0 / EL 2.2, then just pass it as an argument of action/listener method of
UICommand
component orAjaxBehavior
tag. E.g.In combination with:
This only requires that the datamodel is preserved for the form submit request. Best is to put the bean in the view scope by
@ViewScoped
.You can even pass the entire item object:
with:
On Servlet 2.5 containers, this is also possible if you supply an EL implementation which supports this, like as JBoss EL. For configuration detail, see this answer.
Use
<f:param>
inUICommand
component. It adds a request parameter.If your bean is request scoped, let JSF set it by
@ManagedProperty
Or if your bean has a broader scope or if you want more fine grained validation/conversion, use
<f:viewParam>
on the target view, see also f:viewParam vs @ManagedProperty:Either way, this has the advantage that the datamodel doesn't necessarily need to be preserved for the form submit (for the case that your bean is request scoped).
Use
<f:setPropertyActionListener>
inUICommand
component. The advantage is that this removes the need for accessing the request parameter map when the bean has a broader scope than the request scope.In combination with
It'll be just available by property
id
in action method. This only requires that the datamodel is preserved for the form submit request. Best is to put the bean in the view scope by@ViewScoped
.Bind the datatable value to
DataModel<E>
instead which in turn wraps the items.with
(making it
transient
and lazily instantiating it in the getter is mandatory when you're using this on a view or session scoped bean sinceDataModel
doesn't implementSerializable
)Then you'll be able to access the current row by
DataModel#getRowData()
without passing anything around (JSF determines the row based on the request parameter name of the clicked command link/button).This also requires that the datamodel is preserved for the form submit request. Best is to put the bean in the view scope by
@ViewScoped
.Use
Application#evaluateExpressionGet()
to programmatically evaluate the current#{item}
.Which way to choose depends on the functional requirements and whether the one or the other offers more advantages for other purposes. I personally would go ahead with #1 or, when you'd like to support servlet 2.5 containers as well, with #2.
在 JSF 1.2 中,这是通过
(在命令组件内)完成的。在 JSF 2.0(准确地说是 EL 2.2,感谢 BalusC)中,可以这样做:action="${filterList.insert(f.id)}
In JSF 1.2 this was done by
<f:setPropertyActionListener>
(within the command component). In JSF 2.0 (EL 2.2 to be precise, thanks to BalusC) it's possible to do it like this:action="${filterList.insert(f.id)}
在我的视图页面中:
backing bean
In my view page:
backing bean
感谢这个网站作者:Mkyong,实际上为我们传递参数的唯一解决方案是
从
技术上讲,您不能直接传递给方法本身,而是传递给
JSF 请求参数地图
。Thanks to this site by Mkyong, the only solution that actually worked for us to pass a parameter was this
with
Technically, that you cannot pass to the method itself directly, but to the
JSF request parameter map
.