我有一些麻煩讓AJAX調用在Mojarra 2.0.3和PrimeFaces的嵌套複合組件中正確觸發。嵌套的JSF複合組件內的AJAX
子複合材料部件看起來是這樣的:
<cc:interface componentType="therapy">
<cc:attribute name="therapyType" type="java.lang.String" required="true"/>
<cc:attribute name="patientId" type="java.lang.String" required="true"/>
<cc:attribute name="showHistory" type="java.lang.Boolean" required="false" default="true"/>
<cc:attribute name="width" type="java.lang.String" required="false" default="350px"/>
<cc:attribute name="maxHistory" type="java.lang.String" required="false" default="3"/>
<cc:attribute name="collectDoctor" type="java.lang.Boolean" required="false" default="false"/>
<cc:attribute name="collectCareDate" type="java.lang.Boolean" required="false" default="false"/>
<cc:attribute name="important" type="java.lang.Boolean" requred="false" default="false"/>
</cc:interface>
<cc:implementation>
<script>
function #{cc.clientId}Toggle(){
$("##{cc.clientId}_newbutton").toggle();
$("##{cc.clientId}_savebuttons").toggle();
if(#{cc.attrs.collectDoctor}){
$("##{cc.clientId}_doctor").toggle();
}
if(#{cc.attrs.collectCareDate}){
$("##{cc.clientId}_care").toggle();
}
$("##{cc.clientId}_newTherapy").toggle(50);
}
function #{cc.clientId}rowHighlight(event){
if(event.status == 'begin'){
$("##{cc.clientId}_loader").toggle();
}
if(event.status == 'success'){
$("##{cc.clientId}\\:histTable tr:eq(1)").effect("highlight", {color:"#FED17A", easing:"easeInCubic"}, 2000);
}
}
$(function(){
if(#{cc.attrs.important}){
$("div[class~='ui-panel-titlebar'][id^='#{cc.clientId}']").css("background", "#FED17A");
}
});
</script>
<h:form prependId="false">
<p:panel styleClass="mcoPanel" style="width:#{cc.attrs.width};">
<f:facet name="header">
<h:panelGroup>
<span id="#{cc.clientId}_title">#{cc.myType.word}</span>
<span id="#{cc.clientId}_newbutton" class="mcoPanel-controls">
<span onclick="#{cc.clientId}Toggle();">
<h:graphicImage name="page_new.gif" library="images"/>
</span>
</span>
<span id="#{cc.clientId}_savebuttons" class="mcoPanel-controls" style="display:none;">
<span id="#{cc.clientId}_loader" style="display:none;">
<h:graphicImage name="ajax-loader.gif" library="images" height="16" width="16"/>
</span>
<h:commandLink action="#{cc.saveNewTherapy}">
<f:ajax execute="newOnTherapy newExemption newDoctor newCareDate" render="@form" onevent="#{cc.clientId}rowHighlight"/>
<h:graphicImage name="action_save.gif" library="images"/>
</h:commandLink>
<span onclick="#{cc.clientId}Toggle();">
<h:graphicImage name="page_cross.gif" library="images"/>
</span>
</span>
</h:panelGroup>
</f:facet>
<div id="#{cc.clientId}_newTherapy" class="mcoPanel-new" style="display:none;">
<h:outputLabel for="newOnTherapy" value="Satisfied:" style="position:relative; top: -10px;"/>
<p:selectOneMenu id="newOnTherapy" label="Satisfied" value="#{cc.newOnTherapyValue}" style="width: 60px;">
<f:selectItem itemLabel=""/>
<f:selectItems value="#{cc.yesNoList}"/>
</p:selectOneMenu>
<br/>
<h:outputLabel for="newExemption" value="Exemption:" style="position:relative; top: -10px;"/>
<p:selectOneMenu id="newExemption" value="#{cc.newExemption}" style="width: 150px;">
<f:selectItems value="#{cc.exemptions}"/>
</p:selectOneMenu>
<span id="#{cc.clientId}_doctor" style="display:none">
<br/>
<h:outputLabel for="newDoctor" value="Doctor:"/>
<p:inputText id="newDoctor" value="#{cc.newDoctor}"/>
</span>
<span id="#{cc.clientId}_care" style="display:none">
<br/>
<h:outputLabel for="newCareDate" value="Care Date:"/>
<p:calendar id="newCareDate" label="Care Date" value="#{cc.newCareDate}" showButtonPanel="true">
<f:converter converterId="dateOfBirthConverter"/>
</p:calendar>
</span>
</div>
<h:messages id="#{cc.clientId}_messages" errorClass="errorMessage"/>
<p:dataTable id="histTable" value="#{cc.history}" var="item" rendered="#{cc.attrs.showHistory}">
<!-- Table Output -->
</p:dataTable>
</p:panel>
</h:form>
和父複合材料部件看起來是這樣的:
<cc:interface>
<cc:attribute name="title" type="java.lang.String" required="true"/>
</cc:interface>
<cc:implementation>
<h:outputScript name="containerpanel.js" library="js/components" target="head"/>
<p:panel toggleable="true" styleClass="contentPanel" toggleSpeed="500" style="width:1100px;">
<f:facet name="header">
#{cc.attrs.title}
<div class="ui-panel-titlebar-icon ui-corner-all ui-state-default contentSaveAll">
Save All
</div>
<div class="ui-panel-titlebar-icon ui-corner-all ui-state-default contentExpandAll">
++
</div>
<div class="ui-panel-titlebar-icon ui-corner-all ui-state-default contentCollapseAll">
- -
</div>
</f:facet>
<cc:insertChildren>
<!-- Child components go here -->
</cc:insertChildren>
</p:panel>
</cc:implementation>
的實現應該允許任何數量的子組件內容器組件。
子組件發送ajax請求並完美更新其內部組件,如果它們放置在Container組件外的頁面上。另外,如果我使用相同的容器結構,但不是實際的複合組件,則一切正常。
只要將子組件的子組件放置爲Container組件的子組件,這就是事物變得不可靠的地方。在子組件火災未正確Ajax調用(即保存commandLink)用Firebug幫助調試這一點,我已經能夠確定如下:
- AJAX的POST請求似乎被髮送。 「開始」onevent正在發射,並且看着螢火蟲中的控制檯顯示正在向服務器發出的信息,併發送了正確的組件ID和值。
- 支持bean中的操作未被調用。我有一個打印語句作爲第一行,它不是打印。
- ajax請求似乎正在正確完成,一旦發生「成功」。
- 頁面上沒有任何內容正在更新。表單不刷新,頁面頂部的p:messages對象也不刷新。
很顯然,我可以做到這一點,而該容器組件,但我寧願要能當然採取代碼重用的優點。我是否錯過了我需要做的一些事情來讓ajax正常工作?
這似乎不是問題。如果我使用@form,結果是相同的,並且至少根據螢火蟲,正確的id將被髮送回服務器。 – moneyt 2012-07-12 12:52:55
@moneyt它仍然是錯誤的,但老實說,如果正確的ID被髮送執行,我很難過。如果我是你,我會將JSF源文件附加到我的IDE庫並開始通過Mojarra。這可能會給你更多的線索。 – 2012-07-12 12:58:41
你確定這是錯的嗎?在這種情況下,組件ID不是絕對的,而是相對的。我的理解是,如果沒有ID的前導「:」,它不是絕對的,JSF會搜索當前表單以獲得匹配的ID。我想如果它找不到ID,我會得到錯誤告訴我它無法解決它們。 – moneyt 2012-07-12 14:35:39