2017-02-08 83 views
0

Primefaces 6.0。我明白p:remoteCommand的update屬性應該用來指定應該由AJAX更新的組件的clientIds。我想了解PF如何工作。與DataTable相結合,它似乎不像預期的那樣工作。當我嘗試直接設置update="form:dataTable:2:bColumn"時,它沒有效果。但是,這樣做(在下面的代碼中註釋掉)RequestContext.getCurrentInstance().update("form:dataTable:2:bColumn");將強制PF更新指定的outputText。p:remoteCommand的更新屬性如何工作

這是怎麼發生的?我會很高興爲技術解釋 - 我試圖通過調試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; 
    } 

} 

回答

0

基本上JSF ID的客戶端ID是兩個不同的東西(檢查this答案和this後爲了更好的理解)。

當您使用RequestContext.getCurrentInstance().update("form:dataTable:2:bColumn");該方法使用客戶端ID查找必須更新的組件,但在p:remoteCommandupdate屬性的情況下,期待一個JSF ID,而不是生成的客戶端ID,所以that'爲什麼你的更新不起作用。然而,primefaces支持jquery selectors更新組件,所以你可以在一個update財產使用客戶端ID這樣update="@(#yourElementId)"

0

讓我提的是,這是不特定的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"); 

總是絕對的,所以這裏不需要冒號,它會找到元素從根開始(形式'前綴'需要那麼)

+0

您提供的解決方案不起作用。經過更多調試後,我發現remoteCommand被錯誤地轉換爲HTML。在生成的HTML中,我可以看到remoteCall = function(){PrimeFaces.ab({s:「form:j_idt4」,f:「form」,u:「form:dataTable:bColumn」,pa:arguments [0]}) ;}。請注意行號缺失。調試PF的源代碼後,它看起來像一個錯誤。代碼通過首先查找組件(輸出文本字段)來生成此「clientId」。但是在找到它之後,會有一些副作用使clientId字段無效。 –

+1

這是一個分隔問題。在我的答案中描述的方式中,問題中的更新屬性的值是錯誤的。 – Kukeltje