保存

2013-04-09 26 views
2

從backing bean渲染更新的組件我一直在創建一個動態表,它捕獲已更新的所有單元(用於更快保存),然後在保存後刷新/重新保存這些單元。保存

到目前爲止,我創建了表格,所有更新的項目都通過ajax監聽器很好地捕獲,但現在我堅持不能在保存後刷新/重新提交更新的組件。發生從後臺bean

@ManagedBean 
@SessionScoped 
public class RemediationDetail implements Serializable { 
public void markChangedEntity(AjaxBehaviorEvent ajaxEvent){ 
    Entity entity = (Entity) Utility.getAjaxActionAttribute(ajaxEvent, "entity"); 
    //Capture the Client Ids that were updated 
    getComponentsIdsToRefresh().add(ajaxEvent.getComponent().getParent().getClientId()); 
    //Capture what Entities were changed  
    getChangedEntities().add(entity); 
} 

//This is where the save happens and hoping for updating of components !! 
public void processUpdates(AjaxBehaviorEvent event){ 
    entityDomain.processEntities(changedEntities); 

    FacesContext.getCurrentInstance().getPartialViewContext().getRenderIds().addAll(getComponentsIdsToRefresh()); 
} 

} 

保存後

<h:form id="formMain" prependId="false"> 
    <div id="contentWrapper"> 
    <p:messages id="messages" severity="warn, error" autoUpdate="true" closable="true" /> 
    <div style="float:right; position:relative; top: -3px;"> 
     <h:commandButton id="btnSaveUpdates" styleClass="save_updates_button"> 
     <f:ajax execute="@this" listener="#{remediationDetail.processUpdates}"/> 
     </h:commandButton> 
    </div> 
    <h:panelGroup id="detailEdit" styleClass="clear_left" layout="block"> 
    <h:dataTable id="tblDetails" styleClass="slate_table remediation" value="#{remediationDetail.details}" var="dataItem"> 
        <c:forEach items="#{remediationDetail.detailHeaders}" var="key" varStatus="looper"> 
        <h:column> 
         <f:facet name="header">#{key.fieldDefinition.fieldConfiguration.customLabel}</f:facet> 
         <c:if test="#{key.fieldDefinition.dataType.name eq 'Number'}"> 
         <h:panelGroup id="detailNumberPanel#{looper.index}"> 
          <h:inputText id="txtDetailNumber#{looper.index}" rendered="#{remediationDetail.containsErrors(dataItem.id, key.fieldDefinition.id)}" value="#{dataItem.entityList[looper.index].val}" styleClass="remediation_textbox error_marker" title="#{remediationDetail.errorMessages(dataItem.id, key.fieldDefinition.id)}"> 
              <f:convertNumber maxFractionDigits="0" maxIntegerDigits="19"/> 
              <f:ajax event="change" execute="@this" render="@none" listener="#{remediationDetail.markChangedEntity}"/> 
              <f:attribute name="entity" value="#{dataItem.entityList[looper.index]}"/> 
             </h:inputText> 
             <h:outputText id="txtDetailNumberOut#{looper.index}" rendered="#{not remediationDetail.containsErrors(dataItem.id, key.fieldDefinition.id)}" value="#{dataItem.entityList[looper.index].val}"></h:outputText> 
            </h:panelGroup> 
           </c:if> 
         <c:if test="#{key.fieldDefinition.dataType.name eq 'Decimal'}"> 
         <h:panelGroup id="detailDecimalPanel#{looper.index}"> 
          <h:inputText id="txtDetailDecimal#{looper.index}" rendered="#{remediationDetail.containsErrors(dataItem.id, key.fieldDefinition.id)}" converterMessage="Value provided is not a valid Decimal" styleClass="remediation_textbox error_marker" title="#{remediationDetail.errorMessages(dataItem.id, key.fieldDefinition.id)}" value="#{dataItem.entityList[looper.index].val}"> 
              <f:convertNumber maxFractionDigits="2" maxIntegerDigits="19"/> 
              <f:ajax event="change" execute="@this" render="@none" listener="#{remediationDetail.markChangedEntity}"/> 
              <f:attribute name="entity" value="#{dataItem.entityList[looper.index]}"/> 
             </h:inputText> 
             <h:outputText id="txtDetailDecimalOut#{looper.index}" rendered="#{not remediationDetail.containsErrors(dataItem.id, key.fieldDefinition.id)}" value="#{dataItem.entityList[looper.index].val}"> 
              <f:convertNumber maxFractionDigits="2" maxIntegerDigits="19"/> 
             </h:outputText> 
            </h:panelGroup> 
          </c:if> 
         <c:if test="#{key.fieldDefinition.dataType.name eq 'Date'}"> 
         <h:panelGroup id="detailDatePanel#{looper.index}"> 
             <h:inputText id="txtDetailDate#{looper.index}" rendered="#{remediationDetail.containsErrors(dataItem.id, key.fieldDefinition.id)}" styleClass="remediation_textbox error_marker dates" title="#{remediationDetail.errorMessages(dataItem.id, key.fieldDefinition.id)}" value="#{dataItem.entityList[looper.index].val}"> 
              <f:convertDateTime locale="en_US" pattern="MM/dd/yyyy" /> 
              <f:ajax event="change" execute="@this" render="@none" listener="#{remediationDetail.markChangedEntity}"/> 
              <f:attribute name="entity" value="#{dataItem.entityList[looper.index]}"/> 
             </h:inputText> 
             <h:outputText id="txtDetailDateOut#{looper.index}" rendered="#{not remediationDetail.containsErrors(dataItem.id, key.fieldDefinition.id)}" value="#{dataItem.entityList[looper.index].val}"> 
              <f:convertDateTime locale="en_US" pattern="MM/dd/yyyy" /> 
             </h:outputText> 
            </h:panelGroup> 
         </c:if> 
         <c:if test="#{key.fieldDefinition.dataType.name eq 'Boolean'}"> 
         <h:panelGroup id="detailBooleanPanel#{looper.index}"> 
          <h:selectBooleanCheckbox id="cbDetailBooleanInput#{looper.index}" rendered="#{remediationDetail.containsErrors(dataItem.id, key.fieldDefinition.id)}" title="#{remediationDetail.errorMessages(dataItem.id, key.fieldDefinition.id)}" value="#{dataItem.entityList[looper.index].val}"> 
           <f:ajax event="change" execute="@this" render="@none" listener="#{remediationDetail.markChangedEntity}"/> 
              <f:attribute name="entity" value="#{dataItem.entityList[looper.index]}"/> 
             </h:selectBooleanCheckbox> 
          <h:outputText id="txtDetailBooleanOutput#{looper.index}" rendered="#{not remediationDetail.containsErrors(dataItem.id, key.fieldDefinition.id)}" value="#{dataItem.entityList[looper.index].val}"></h:outputText> 
         </h:panelGroup> 
          </c:if> 
         <c:if test="#{key.fieldDefinition.dataType.name eq 'String'}"> 
         <h:panelGroup id="detailStringPanel#{looper.index}"> 
           <h:inputText id="txtDetailString#{looper.index}" rendered="#{key.fieldDefinition.inputType eq 'TEXTBOX' and remediationDetail.containsErrors(dataItem.id, key.fieldDefinition.id)}" value="#{dataItem.entityList[looper.index].val}" styleClass="remediation_textbox error_marker" title="#{remediationDetail.errorMessages(dataItem.id, key.fieldDefinition.id)}"> 
              <f:ajax event="change" execute="@this" render="@none" listener="#{remediationDetail.markChangedEntity}"/> 
              <f:attribute name="entity" value="#{dataItem.entityList[looper.index]}"/> 
             </h:inputText> 
             <h:selectOneMenu id="ddDetailString#{looper.index}" styleClass="remediation_select error_marker" rendered="#{key.fieldDefinition.inputType eq 'DROPDOWN' and remediationDetail.containsErrors(dataItem.id, key.fieldDefinition.id)}" value="#{dataItem.entityList[looper.index].val}" title="#{remediationDetail.errorMessages(dataItem.id, key.fieldDefinition.id)}"> 
              <f:selectItems value="#{dataItem.entityList[looper.index].fieldDefinition.listItemSet.selectItemsList}"></f:selectItems> 
              <f:ajax event="change" execute="@this" render="@none" listener="#{remediationDetail.markChangedEntity}"/> 
              <f:attribute name="entity" value="#{dataItem.entityList[looper.index]}"/> 
             </h:selectOneMenu> 
             <h:outputText id="txtDetailStringOut#{looper.index}" rendered="#{not remediationDetail.containsErrors(dataItem.id, key.fieldDefinition.id)}" value="#{dataItem.entityList[looper.index].val}"></h:outputText> 
            </h:panelGroup> 
         </c:if> 
        </h:column> 
        </c:forEach> 
       </h:dataTable> 
      </h:panelGroup> 
     </div> 
    </h:form> 

代碼,我添加的客戶ID更新到PartialViewContext()getRenderIds(:從頁面

代碼段。 )我沒有看到任何更新。我也嘗試過OmniFaces Ajax.Update(clientId),但沒有成功。

我更新了代碼片段,因爲它目前與正在構建的完整表站在一起。

我的問題是:

  1. 是我在做什麼可能?
  2. 我接近正確渲染組件嗎?
  3. 我錯過了什麼?

我的環境: 鑽嘴魚科2.1.7 Tomcat的7.022

問候,

邁克

+0

你是積極的組件您指定更新的組件是有效的?你的Javascript控制檯說什麼? – kolossus 2013-04-09 20:19:01

+0

@kolossus是的!我肯定回顧了傳遞給後臺bean的內容以及頁面上可用的內容。更進一步,我通過將「formMain:」預先加入ID,甚至是「:formMain:」來改變它的值,因爲它已經在f:ajax標記的渲染部分中使用了,至此買不起任何東西。 – MikeR 2013-04-09 21:12:37

+0

@MikeR什麼是託管bean的範圍? – partlov 2013-04-11 14:00:36

回答

0

此代碼適用於Mojarra 2.1.21。 Mojarra 2.1.7從2012年3月開始,目前已經有一年多一點的時間了。我強烈建議升級它。

我不能精確地指出2.1.7和2.1.21之間的哪個版本和/或哪個Mojarra issue用2.1.7修復了具體問題,因爲我不認識這個問題,但我可以說很多最近在國家視野管理方面有所改進。更重要的是,從2.1.18開始,eternal chicken-egg problem with taglibs+viewscope已經修復,不妨關注一下。

0

我注意到你的markChangedEntity方法的東西。您有以下代碼:

getComponentsIdsToRefresh().add("formMain:" + 
    ajaxEvent.getComponent().getParent().getClientId()); 

調用getClientId()已經返回完整的ID,包括形式的ID。添加formMain:將導致類似於formMain:formMain:XXX,這在您的視圖中不會是合法ID。

+0

這真奇怪。編輯前的原始問題代碼沒有發生錯誤。我不確定在編制/編輯問題時這是否只是粗心大意。 – BalusC 2013-04-14 11:35:10

+0

@Michi「:formMain:」在我原來的文章中並沒有出現,並且在我嘗試解決這個問題時被添加了。這裏有點粘性了..我改變了我如何捕獲身份證,現在它可以工作,但只有當我將它與BalusC將JSF版本升級到2.1.21的建議結合使用時纔有效。這應如何處理? – MikeR 2013-04-15 02:25:46

+0

@Michi另外,作爲一個快速評論。檢查getClientId()我沒有看到返回的值中的表單。它只返回到表格標籤。 – MikeR 2013-04-15 02:31:40