本文介绍了dataTable中的JSF PrimeFaces inputText的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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:remoteCommandp: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:remoteCommandname属性中定义的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());

注意:在更新每一行的面板时,也许您可​​以将remoteCommandupdate属性更改为@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的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

07-28 06:07