【问题标题】:JSF PrimeFaces inputText inside dataTable数据表中的 JSF PrimeFaces inputText
【发布时间】:2013-02-06 02:15:37
【问题描述】:

JSF-2.0、Mojarra 2.1.19、PrimeFaces 3.4.1

问题总结:在p:dataTable 内有一个p:inputText 和由p:remoteCommand 触发的inputText 操作,它将dataTable 行索引作为f:setPropertyActionListener 的参数传递。但它总是传递数据表的最后一行,而不是包含当前点击的行的索引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 属于p:statusList 中的最后一个状态。它必须是 1,即点击 dataTable 行的p:inputText 的索引。

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


它是如何工作的?

假设有一个p:commandLink 而不是p:remoteCommand 和p:inputText:

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

此组件成功传递indexStatusList 作为当前单击的一个。

【问题讨论】:

    标签: jsf jsf-2 primefaces


    【解决方案1】:

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

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

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

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

    这将在您的 AJAX 请求中传递 rowNumber 参数。在支持 bean 的 insertComment() 方法中,您可以读取此参数并对其进行任何操作:

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

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

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

    RequestContext.getCurrentinstance().update("form:dataTable:" + rowNumber + ":statusRepeatPanel")
    

    【讨论】:

    • 非常感谢我的朋友。我将在完成 js 函数以正确更新视图层后查看更新值。
    • 老兄有什么办法可以在 remoteCommand 中执行 update="form:dataTable:#{rowNumber}:statusRepeatPanel"。因为我不想更新整个表单?
    • 在rowNumber初始化后尝试在服务器方法中添加RequestContext.getCurrentinstance().update("form:dataTable:" + rowNumber + ":statusRepeatPanel")。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-11-25
    • 1970-01-01
    • 2012-11-22
    • 1970-01-01
    • 1970-01-01
    • 2011-01-19
    • 1970-01-01
    相关资源
    最近更新 更多