ค้นหาเอาต์พุต HTML เพื่อหารหัสลูกค้าที่แท้จริง
คุณต้องมองหาผลลัพธ์ HTML ที่สร้างขึ้นเพื่อหารหัสลูกค้าที่ถูกต้อง เปิดหน้าในเบราว์เซอร์, คลิกขวาทำและดูแหล่งที่มา ค้นหาการเป็นตัวแทน HTML ขององค์ประกอบ JSF ที่น่าสนใจและใช้idเป็น ID ลูกค้า คุณสามารถใช้มันในแบบสัมบูรณ์หรือแบบสัมพันธ์โดยขึ้นอยู่กับคอนเทนเนอร์การตั้งชื่อปัจจุบัน ดูบทต่อไปนี้
หมายเหตุ: หากมีดัชนีการทำซ้ำเช่น:0:, :1:ฯลฯ (เนื่องจากอยู่ในองค์ประกอบการทำซ้ำ) คุณจะต้องตระหนักว่าการอัพเดตรอบการทำซ้ำที่เฉพาะเจาะจงนั้นไม่ได้รับการสนับสนุนเสมอไป ดูคำตอบด้านล่างเพื่อดูรายละเอียดเพิ่มเติม
จดจำNamingContainerส่วนประกอบและให้รหัสประจำตัวแก่พวกเขาเสมอ
หากส่วนประกอบที่คุณต้องการอ้างอิงโดย ajax process / execute / update / render อยู่ในพาเรนต์เดียวกันNamingContainerให้อ้างอิง ID ของตัวเอง
<h:form id="form">
<p:commandLink update="result"> <!-- OK! -->
<h:panelGroup id="result" />
</h:form>
หากไม่ใช่ภายในเดียวกันNamingContainerคุณจำเป็นต้องอ้างอิงโดยใช้รหัสลูกค้าแบบสัมบูรณ์ รหัสลูกค้าแน่นอนเริ่มต้นด้วยตัวอักษรที่คั่นซึ่งเป็นค่าเริ่มต้นNamingContainer:
<h:form id="form">
<p:commandLink update="result"> <!-- FAIL! -->
</h:form>
<h:panelGroup id="result" />
<h:form id="form">
<p:commandLink update=":result"> <!-- OK! -->
</h:form>
<h:panelGroup id="result" />
<h:form id="form">
<p:commandLink update=":result"> <!-- FAIL! -->
</h:form>
<h:form id="otherform">
<h:panelGroup id="result" />
</h:form>
<h:form id="form">
<p:commandLink update=":otherform:result"> <!-- OK! -->
</h:form>
<h:form id="otherform">
<h:panelGroup id="result" />
</h:form>
NamingContainerเป็นส่วนประกอบเช่น<h:form>, <h:dataTable>, <p:tabView>, <cc:implementation>(ดังนั้นทุกองค์ประกอบคอมโพสิต) ฯลฯ คุณรู้จักพวกเขาได้อย่างง่ายดายโดยดูที่การแสดงผล HTML สร้าง ID ของพวกเขาจะใช้ได้กับรหัสลูกค้าที่สร้างขึ้นของทุกองค์ประกอบเด็ก โปรดทราบว่าเมื่อพวกเขาไม่มีรหัสคงที่ JSF จะใช้รหัสที่สร้างอัตโนมัติในj_idXXXรูปแบบ คุณควรหลีกเลี่ยงอย่างนั้นด้วยการให้รหัสประจำตัวแก่พวกเขา OmniFacesNoAutoGeneratedIdViewHandlerอาจจะเป็นประโยชน์ในเรื่องนี้ในระหว่างการพัฒนา
หากคุณรู้ที่จะหา javadoc ของUIComponentคำถามนั้นคุณสามารถเพียงแค่เช็คอินที่นั่นไม่ว่าจะใช้NamingContainerอินเทอร์เฟซหรือไม่ ยกตัวอย่างเช่นHtmlForm(คนUIComponentที่อยู่เบื้องหลัง<h:form>แท็ก) แสดงให้เห็นว่าการดำเนินการNamingContainerแต่HtmlPanelGroup(คนUIComponentที่อยู่เบื้องหลัง<h:panelGroup>แท็ก) NamingContainerไม่ได้แสดงมันจึงไม่ได้ดำเนินการ นี่คือ Javadoc ของส่วนประกอบทั้งหมดมาตรฐานและนี่คือ Javadoc ของ PrimeFaces
การแก้ปัญหาของคุณ
ดังนั้นในกรณีของคุณ:
<p:tabView id="tabs"><!-- This is a NamingContainer -->
<p:tab id="search"><!-- This is NOT a NamingContainer -->
<h:form id="insTable"><!-- This is a NamingContainer -->
<p:dialog id="dlg"><!-- This is NOT a NamingContainer -->
<h:panelGrid id="display">
ผลลัพธ์ HTML ที่สร้างขึ้น<h:panelGrid id="display">มีลักษณะดังนี้:
<table id="tabs:insTable:display">
คุณต้องปฏิบัติตามนั้นidเหมือนเป็นรหัสลูกค้าจากนั้นนำหน้าด้วย:สำหรับการใช้งานในupdate:
<p:commandLink update=":tabs:insTable:display">
การอ้างอิงภายนอก ได้แก่ / tagfile / composite
หากลิงก์คำสั่งนี้อยู่ใน include / tagfile และเป้าหมายอยู่ข้างนอกและทำให้คุณไม่จำเป็นต้องทราบ ID ของพาเรนต์คอนเทนเนอร์หลักของคอนเทนเนอร์การตั้งชื่อปัจจุบันของคอนเทนเนอร์การตั้งชื่อปัจจุบันคุณสามารถอ้างอิงได้แบบไดนามิกUIComponent#getNamingContainer()ดังนี้:
<p:commandLink update=":#{component.namingContainer.parent.namingContainer.clientId}:display">
หรือหากลิงก์คำสั่งนี้อยู่ในส่วนประกอบคอมโพสิตและเป้าหมายอยู่ข้างนอก:
<p:commandLink update=":#{cc.parent.namingContainer.clientId}:display">
หรือถ้าทั้งลิงค์คำสั่งและเป้าหมายอยู่ในองค์ประกอบคอมโพสิตเดียวกัน:
<p:commandLink update=":#{cc.clientId}:display">
ดูเพิ่มเติมรับid ของการตั้งชื่อพาเรนต์คอนเทนเนอร์ในเทมเพลตสำหรับในแอตทริบิวต์การแสดงผล / อัปเดต
มันทำงานอย่างไรภายใต้ผ้าคลุม
ทั้งหมดนี้มีการระบุเป็น"การแสดงออกค้นหา"ในJavadoc :UIComponent#findComponent()
แสดงออกค้นหาประกอบด้วยทั้งระบุ (ซึ่งจะถูกจับคู่ตรงกับรหัสทรัพย์สินของUIComponentหรือชุดของตัวบ่งชี้ดังกล่าวเชื่อมโยงโดยที่UINamingContainer#getSeparatorCharค่าของตัวอักษร. วิธีการค้นหาควรดำเนินงานดังต่อไปนี้แม้ว่า alogrithms อื่นอาจจะใช้ตราบใดที่ ผลลัพธ์ที่ได้จะเหมือนกัน:
- ระบุสิ่ง
UIComponentที่จะเป็นฐานในการค้นหาโดยหยุดทันทีที่พบเงื่อนไขใด ๆ
- หากนิพจน์การค้นหาเริ่มต้นด้วยอักขระตัวคั่น (เรียกว่านิพจน์การค้นหา "สัมบูรณ์") ฐานจะเป็นรูท
UIComponentของโครงสร้างคอมโพเนนต์ อักขระคั่นนำหน้าจะถูกตัดออกและส่วนที่เหลือของนิพจน์การค้นหาจะถูกใช้เป็นนิพจน์การค้นหา "สัมพัทธ์" ตามที่อธิบายไว้ด้านล่าง
- มิฉะนั้นถ้านี่
UIComponentคือสิ่งที่NamingContainerมันจะทำหน้าที่เป็นพื้นฐาน
- มิฉะนั้นค้นหาผู้ปกครองของส่วนนี้ หาก
NamingContainerพบจะเป็นฐาน
- มิฉะนั้น (หากไม่
NamingContainerพบ) รูทUIComponentจะเป็นฐาน
- นิพจน์การค้นหา (อาจแก้ไขในขั้นตอนก่อนหน้า) ตอนนี้เป็นนิพจน์การค้นหา "สัมพัทธ์" ที่จะถูกใช้เพื่อค้นหาส่วนประกอบ (ถ้ามี) ที่มีรหัสที่ตรงกันภายในขอบเขตขององค์ประกอบพื้นฐาน การแข่งขันจะดำเนินการดังนี้:
- หากนิพจน์การค้นหาเป็นตัวบ่งชี้แบบง่ายค่านี้จะถูกเปรียบเทียบกับคุณสมบัติ id จากนั้นทำการวนซ้ำผ่าน facets และลูก ๆ ของฐาน
UIComponent(ยกเว้นว่าหากNamingContainerพบการสืบทอดตำแหน่ง facets และลูกของมันจะไม่ถูกค้นหา)
- หากนิพจน์การค้นหามีตัวระบุมากกว่าหนึ่งตัวคั่นด้วยอักขระตัวคั่นตัวระบุแรกจะถูกใช้เพื่อค้นหา
NamingContainerกฎโดยในสัญลักษณ์ก่อนหน้า จากนั้นจะเรียกfindComponent()วิธีการนี้NamingContainerผ่านส่วนที่เหลือของนิพจน์การค้นหา
โปรดทราบว่า PrimeFaces ยังยึดมั่นในข้อมูลจำเพาะ JSF แต่ RichFaces ใช้"ข้อยกเว้นเพิ่มเติมบางอย่าง"
"reRender"ใช้UIComponent.findComponent()อัลกอริทึม (มีข้อยกเว้นเพิ่มเติมบางอย่าง) เพื่อค้นหาส่วนประกอบในโครงสร้างองค์ประกอบ
ข้อยกเว้นเพิ่มเติมเหล่านั้นไม่มีรายละเอียดอธิบายไว้ แต่เป็นที่ทราบกันว่า ID ส่วนประกอบที่เกี่ยวข้อง (เช่นที่ไม่ได้ขึ้นต้นด้วย:) ไม่เพียงค้นหาในบริบทของพาเรนต์ที่ใกล้ที่สุดNamingContainerแต่ยังอยู่ในNamingContainerส่วนประกอบอื่น ๆ ทั้งหมดในมุมมองเดียวกัน งานแพง ๆ )
ห้ามใช้ prependId="false"
<h:form prependId="false">หากทั้งหมดนี้ยังไม่ได้ทำงานแล้วตรวจสอบว่าคุณไม่ได้ใช้ สิ่งนี้จะล้มเหลวระหว่างการประมวลผล ajax submit และ render ดูเพิ่มเติมนี้คำถามที่เกี่ยวข้อง: UIForm กับ prependId = แบ่ง "false" <f: อาแจ็กซ์ทำให้>
การอ้างอิงรอบการวนซ้ำเฉพาะของส่วนประกอบการวนซ้ำ
มันเป็นเวลานานไม่ได้ที่จะอ้างอิงเฉพาะซ้ำรายการในการทำซ้ำเช่นส่วนประกอบ<ui:repeat>และ<h:dataTable>ชอบโดย:
<h:form id="form">
<ui:repeat id="list" value="#{['one','two','three']}" var="item">
<h:outputText id="item" value="#{item}" /><br/>
</ui:repeat>
<h:commandButton value="Update second item">
<f:ajax render=":form:list:1:item" />
</h:commandButton>
</h:form>
อย่างไรก็ตามเนื่องจาก Mojarra 2.2.5 ผู้<f:ajax>สนับสนุนเริ่มต้นแล้ว (เพียงแค่หยุดการตรวจสอบความถูกต้องเท่านั้นดังนั้นคุณจะไม่พบกับข้อยกเว้นในคำถามที่กล่าวถึงอีกต่อไป;
สิ่งนี้ไม่สามารถใช้งานได้ในเวอร์ชันปัจจุบันของ MyFaces 2.2.7 และ PrimeFaces 5.2 การสนับสนุนอาจมาในรุ่นอนาคต ในขณะเดียวกันทางออกที่ดีที่สุดของคุณคือการปรับปรุงองค์ประกอบ iterating ตัวเองหรือผู้ปกครองในกรณีที่ไม่สามารถแสดงได้ HTML <ui:repeat>เช่น
เมื่อใช้ PrimeFaces ให้พิจารณานิพจน์การค้นหาหรือตัวเลือก
PrimeFaces Search Expressionsอนุญาตให้คุณอ้างอิงคอมโพเนนต์ผ่านนิพจน์การค้นหาแผนผังองค์ประกอบ JSF JSF มีหลายบิลด์:
@this: องค์ประกอบปัจจุบัน
@form: ผู้ปกครอง UIForm
@all: เอกสารทั้งหมด
@none: ไม่มีอะไร
PrimeFaces ได้ปรับปรุงสิ่งนี้ด้วยคำหลักใหม่และการสนับสนุนการแสดงออกรวม:
@parent: องค์ประกอบหลัก
@namingcontainer: ผู้ปกครอง UINamingContainer
@widgetVar(name): องค์ประกอบตามที่ระบุโดยกำหนด widgetVar
นอกจากนี้คุณยังสามารถผสมคำหลักเหล่านั้นในการแสดงออกเช่นคอมโพสิต@form:@parent, @this:@parent:@parentฯลฯ
PrimeFaces Selectors (PFS)เช่นเดียวกับใน@(.someclass)ช่วยให้คุณสามารถอ้างอิงส่วนประกอบผ่านทางไวยากรณ์ตัวเลือก jQuery CSS เช่นการอ้างอิงส่วนประกอบที่มีคลาสสไตล์ทั่วไปทั้งหมดในเอาต์พุต HTML สิ่งนี้มีประโยชน์อย่างยิ่งในกรณีที่คุณต้องการอ้างอิงส่วนประกอบ "มาก" สิ่งนี้จำเป็นก่อนว่าองค์ประกอบเป้าหมายมีรหัสลูกค้าทั้งหมดในเอาต์พุต HTML (แก้ไขหรือสร้างอัตโนมัติไม่สำคัญ) ดูเพิ่มเติมPrimeFaces Selectors เช่นเดียวกับใน update = "@ (. myClass)" ทำงานอย่างไร