问题描述
JSF-2.0,Mojarra 2.1.19,PrimeFaces 3.4.1
问题摘要:在p:dataTable
内有一个p:inputText
,并由p:remoteCommand
触发了inputText操作,该操作将dataTable行索引作为参数传递给f:setPropertyActionListener
.但它始终传递dataTable的最后一行,而不传递包含当前单击的p:inputText
的行的索引.
Summary of the problem: Have a p:inputText
inside p:dataTable
and inputText action fired by p:remoteCommand
which passes the dataTable row index as a parameter with f:setPropertyActionListener
. But it always passes the last row of the dataTable, not the index of the row which includes currently clicked p:inputText
.
从我之前的问题中可以看出,我正在尝试将p:inputText
用作Facebook等状态的评论者.实现包括p:dataTable
.它的行代表每个状态.好像是:
As it can be seen from my previous questions, I am trying to use p:inputText
as a comment taker for a status like in Facebook or etc. Implementation includes a p:dataTable
. It's rows represents each status. Seems like:
<p:dataTable id="dataTable" value="#{statusBean.statusList}" var="status"
rowIndexVar="indexStatusList">
<p:column>
<p:panel id="statusRepeatPanel">
<p:remoteCommand name="test" action="#{statusBean.insertComment}"
update="statusRepeatPanel">
<f:setPropertyActionListener
target="#{statusBean.indexStatusList}"
value="#{indexStatusList}">
</f:setPropertyActionListener>
</p:remoteCommand>
<p:inputText id="commentInput" value="#{statusBean.newComment}"
onkeypress="if (event.keyCode == 13) { test(); return false; }">
</p:inputText>
</p:panel>
</p:column>
</p:dataTable>
上部代码表示,当按下回车键时,触发p:remoteCommand
,它调用托管bean的insert方法.
Upper code says when the press enter key, fire p:remoteCommand
which calls the insert method of the managed bean.
@ManagedBean
@ViewScoped
public class StatusBean {
List<Status> statusList = new ArrayList<Status>();
public int indexStatusList;
public String newComment
//getters and setters
public void insertComment() {
long statusID = findStatusID(statusList.get(indexStatusList));
statusDao.insert(this.newComment,statusID)
}
一起调试吧;假设p:dataTable
中显示了三种状态,请单击p:inputText
,在 second 状态(索引为1)中,键入"relax",然后按输入密钥.
Let's debug together; assuming there are three statuses shown in the p:dataTable
, click in the p:inputText
which in the second status(index of 1), type "relax" and press the enter key.
在调试控制台中,它正确显示松弛",但是它找到了错误的状态,因为indexStatusList
的值为2,它属于p:statusList
中的最后一个状态.它必须为1,这是在dataTable行上单击的p:inputText
的索引.
In the debug console, it correctly shows "relax", but it finds the wrong status because indexStatusList
has the value of 2 which belongs the last status in the p:statusList
. It must be 1 which is the index of p:inputText
that clicked on the dataTable row.
我认为问题出在p:remoteCommand
上,它占用了屏幕上的最后一个索引.
I think problem is about p:remoteCommand
which takes the last index on the screen.
它如何工作?
让我们想象有一个p:commandLink
而不是p:remoteCommand
和p:inputText
:
Let's imagine there is a p:commandLink
instead of p:remoteCommand
and p:inputText
:
<p:commandLink action=#{statusBean.insertComment>
<f:setPropertyActionListener target="#{statusBean.indexStatusList}"
value="#{indexStatusList}"></f:setPropertyActionListener>
此组件成功通过了当前单击的indexStatusList
.
This component successfully passes the indexStatusList
as currently clicked one.
推荐答案
此解决方案中的概念问题在于p:remoteCommand
的工作方式.它创建名称在p:remoteCommand
的name
属性中定义的JavaScript函数.如您在dataTable
中所述,它将迭代并创建称为test
的JavaScript函数,其次数与该表中的行数相同,最后,最后一个将只有一个.因此,解决方案可以是在remoteCommand
的名称后附加索引,但这很不好,因为您将有许多不必要的JavaScript函数.更好的方法是创建一个函数的传递参数.因此,在数据表之外定义remoteCommand
:
Conceptual problem in this solution lies in way how p:remoteCommand
works. It creates JavaScript function whose name is defined in name
attribute of p:remoteCommand
. As you putted this in dataTable
it will iterate and create JavaScript function called test
as many times as there is rows in this table, and at the end last one will be only one. So, solution can be in appending index at the name of the remoteCommand
but that is bad, because you will have many unnecessary JavaScript functions. Better approach would be to create one function an pass argument to it. So define remoteCommand
outside of datatable:
<p:remoteCommand name="test" action="#{statusBean.insertComment}" update="statusRepeatPanel">
并在onkeypress
事件中调用test
函数,如下所示:
and call test
function like this in your onkeypress
event:
test([{ name: 'rowNumber', value: #{indexStatusList} }])
这将在您的AJAX请求中传递rowNumber
参数.在支持bean的insertComment()
方法中,您可以读取此参数并对其进行任何所需的操作:
This will pass rowNumber
parameter in your AJAX request. In backing bean's insertComment()
method you can read this parameter and do with it anything you want:
FacesContext context = FacesContext.getCurrentInstance();
Map map = context.getExternalContext().getRequestParameterMap();
Integer rowNumber = Integer.parseInt(map.get("rowNumber").toString());
注意:在更新每一行的面板时,也许您可以将remoteCommand
的update
属性更改为@parent
,所以这将适用于所有行.
NOTE: as you are updating panel in each row, maybe you can change update
attribute of remoteCommand
to @parent
so this will work for all rows.
您可以使用Java方法中的以下代码更新特定行中的特定面板:
You can update the specific panel in specific row with following code in Java method:
RequestContext.getCurrentinstance().update("form:dataTable:" + rowNumber + ":statusRepeatPanel")
这篇关于dataTable中的JSF PrimeFaces inputText的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!