【问题标题】:How update attribute of p:remoteCommand worksp:remoteCommand 的更新属性如何工作
【发布时间】:2017-06-26 05:12:17
【问题描述】:

Primefaces 6.0。我知道应该使用 p:remoteCommand 的更新属性来指定应该由 AJAX 更新的组件的 clientIds。我试图了解 PF 是如何工作的。与 DataTable 结合使用,它似乎没有按预期工作。当我尝试直接设置update="form:dataTable:2:bColumn" 时,它没有效果。但是,这样做(在下面的代码中注释掉)RequestContext.getCurrentInstance().update("form:dataTable:2:bColumn"); 将强制 PF 更新指定的 outputText。

为什么会这样?我很乐意接受技术解释 - 我正在尝试通过调试 PF Java/Javascript 源来找到答案。

<h:form id="form">
    <p:remoteCommand name="remoteCall"
                     action="#{grid4.onEdit}"
                     update="form:dataTable:2:bColumn"
    />

    <p:dataTable id="dataTable"
                 var="gridItem"
                 value="#{grid4.gridItems}"
                 editable="true" editMode="cell"
    >

        <p:ajax event="cellEdit"
                oncomplete="remoteCall()">
        </p:ajax>

        <p:column headerText="A">
            <p:cellEditor>
                <f:facet name="output"><h:outputText value="#{gridItem.a}" /></f:facet>
                <f:facet name="input"><p:inputText value="#{gridItem.a}"/></f:facet>
            </p:cellEditor>
        </p:column>
        <p:column headerText="B">
            <h:outputText id="bColumn" value="#{gridItem.b}" />
        </p:column>
    </p:dataTable>

</h:form>

豆子

@ManagedBean
@ViewScoped
public class Grid4 {
    private List<GridItem> gridItems = new ArrayList<>();


    public Grid4() {
        gridItems.add(new GridItem("1", "a","b"));
        gridItems.add(new GridItem("2", "a","b"));
        gridItems.add(new GridItem("3", "a","b"));
    }

    public void onEdit() {
        System.out.println("onEdit()");
        gridItems.get(2).setB("CHANGED VALUE");
//        RequestContext.getCurrentInstance().update("form:dataTable:2:bColumn");
    }

    public List<GridItem> getGridItems() {
        return gridItems;
    }

    public void setGridItems(List<GridItem> gridItems) {
        this.gridItems = gridItems;
    }

}

【问题讨论】:

    标签: jsf primefaces datatable


    【解决方案1】:

    基本上 jsf ids 和客户端 ids 是两个不同的东西(查看this 答案和this 帖子以获得更好的理解)。

    当您使用 RequestContext.getCurrentInstance().update("form:dataTable:2:bColumn"); 时,该方法使用客户端 ID 来查找必须更新的组件,但在 p:remoteCommandupdate 属性的情况下,它需要一个 jsf id,而不是生成的客户端id,所以这就是您的更新不起作用的原因。但是,primefaces 支持 jquery selectors 更新组件,因此您可以在 update 属性上使用客户端 ID,例如 update="@(#yourElementId)"

    【讨论】:

    • 对 jquery 选择器一无所知。谢谢!!
    【解决方案2】:

    首先让我提到这不是特定于p:remoteCommand。您注意到这种行为的原因相当简单,尽管可能不是很明显,因为很遗憾它不在 PrimeFaces 文档中。

    更新属性在:

    <p:remoteCommand name="remoteCall"
                     action="#{grid4.onEdit}"
                     update="form:dataTable:2:bColumn"
    />
    

    如果它不以 : 开头,则使用相对路径,并且由于 p:remoteCommand 已经在带有 id='form' 的命名容器中,更新属性中的表单是多余的,甚至使它不起作用(运行你的应用程序在开发模式下,添加消息标签并查看错误)。

    所以

    <p:remoteCommand name="remoteCall"
                     action="#{grid4.onEdit}"
                     update="dataTable:2:bColumn"
    />
    

    应该可以工作

    <p:remoteCommand name="remoteCall"
                     action="#{grid4.onEdit}"
                     update=":form:dataTable:2:bColumn"
    />
    

    RequestContext.getCurrentInstance().update("form:dataTable:2:bColumn");
    

    always绝对的,所以这里不需要冒号,它会从根开始查找元素(然后需要form'prefix')

    【讨论】:

    • 您提供的解决方案不起作用。经过更多调试后,我发现 remoteCommand 被错误地翻译成 HTML。在生成的 HTML 中,我可以看到 remoteCall = function() {PrimeFaces.ab({s:"form:j_idt4",f:"form",u:"form:dataTable:bColumn",pa:arguments[0]}) ;}。请注意,缺少行号。调试PF的源代码后,看起来是个bug。代码首先通过查找组件(输出文本字段)来生成此“clientId”。但是在找到它之后,会有一些副作用使 clientId 字段无效。
    • 这是一个单独的问题。您问题中更新属性的值与我在回答中描述的方式错误。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-02-10
    • 2011-07-10
    相关资源
    最近更新 更多