p:remoteCommand的update属性如何工作

时间:2017-02-08 14:19:15

标签: jsf primefaces datatable

Primefaces 6.0。我知道p:remoteCommand的update属性应该用于指定应该由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;
    }

}

2 个答案:

答案 0 :(得分:1)

基本上jsf ids客户端ID是两个不同的东西(检查this回答和this 帖子以便更好地理解)。

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

答案 1 :(得分:0)

首先我要提一下,这不是p:remoteCommand所特有的。您注意到的行为的原因相当简单,但并非直接明显,因为遗憾的是,它不在PrimeFaces文档中。

更新属性:

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

如果它不以a开头,则使用相对路径;并且由于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");

总是绝对,所以这里不需要冒号,它会找到从根开始的元素(然后需要使用'prefix'形式)