3

JSF-2.0、Mojarra 2.1.19、PrimeFaces 3.4.1

问题总结:有一个p:inputTextinsidep:dataTable和 inputText 动作,通过p:remoteCommand它传递 dataTable 行索引作为参数f:setPropertyActionListener。但它总是通过 dataTable 的最后一行,而不是包含当前 clicked 的行的索引p:inputText


从我之前的问题可以看出,我正在尝试p:inputText用作 Facebook 等状态的评论接受者。实现包括p:dataTable. 它的行代表每个状态。看起来像:

<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的插入方法的触发。

@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状态(索引为1)中单击p:inputText其中,输入“relax”并按回车键。

在调试控制台中,它正确显示“放松”,但它发现了错误的状态,因为indexStatusList值 2 属于. 它必须是 1,这是在 dataTable 行上单击的索引。 p:statusListp:inputText

我认为问题在于p:remoteCommand屏幕上的最后一个索引。


这个怎么运作?

让我们想象有一个p:commandLink代替p:remoteCommandand p:inputText

<p:commandLink action=#{statusBean.insertComment>
      <f:setPropertyActionListener target="#{statusBean.indexStatusList}"
          value="#{indexStatusList}"></f:setPropertyActionListener>

这个组件成功地传递了indexStatusList当前点击的那个。

4

1 回答 1

1

此解决方案中的概念问题在于工作方式p:remoteCommand。它创建 JavaScript 函数,其名称在 的name属性中定义p:remoteCommand。当您将其放入dataTable时,它将迭代并创建 JavaScript 函数,该函数被调用test的次数与该表中的行数一样多,最后最后一个将只有一个。因此,解决方案可以是在名称处附加索引,remoteCommand但这很糟糕,因为您将拥有许多不必要的 JavaScript 函数。更好的方法是创建一个函数作为传递参数。所以remoteCommand在数据表之外定义:

<p:remoteCommand name="test" action="#{statusBean.insertComment}" update="statusRepeatPanel">

test并在您的onkeypress事件中调用这样的函数:

test([{ name: 'rowNumber', value: #{indexStatusList} }])

这将rowNumber在您的 AJAX 请求中传递参数。在支持 bean 的insertComment()方法中,您可以读取此参数并使用它做任何您想做的事情:

FacesContext context = FacesContext.getCurrentInstance();
Map map = context.getExternalContext().getRequestParameterMap();
Integer rowNumber = Integer.parseInt(map.get("rowNumber").toString());

注意:当您在每一行中更新面板时,也许您可​​以将update属性更改为remoteCommand@parent这样这将适用于所有行。

编辑:您可以使用 Java 方法中的以下代码更新特定行中的特定面板:

RequestContext.getCurrentinstance().update("form:dataTable:" + rowNumber + ":statusRepeatPanel")
于 2013-02-20T22:28:02.460 回答