Lihat keluaran HTML untuk ID klien yang sebenarnya
Anda perlu melihat output HTML yang dihasilkan untuk mengetahui ID klien yang tepat. Buka halaman di browser, lakukan klik kanan dan View Source . Temukan representasi HTML dari komponen JSF yang diinginkan dan ambilid
sebagai ID klien. Anda dapat menggunakannya dengan cara absolut atau relatif bergantung pada wadah penamaan saat ini. Lihat bab berikut.
Catatan: jika kebetulan mengandung indeks iterasi seperti :0:
,, :1:
dll (karena berada di dalam komponen iterasi), maka Anda perlu menyadari bahwa memperbarui putaran iterasi tertentu tidak selalu didukung. Lihat bagian bawah jawaban untuk detail lebih lanjut tentang itu.
Hafalkan NamingContainer
komponen dan selalu beri mereka ID tetap
Jika sebuah komponen yang ingin Anda referensikan dengan ajax process / execution / update / render berada di dalam NamingContainer
induk yang sama , maka cukup referensikan ID-nya sendiri.
<h:form id="form">
<p:commandLink update="result">
<h:panelGroup id="result" />
</h:form>
Jika tidak ada di dalamnya NamingContainer
, Anda perlu mereferensikannya menggunakan ID klien absolut. ID klien absolut dimulai dengan NamingContainer
karakter pemisah, yang secara default :
.
<h:form id="form">
<p:commandLink update="result">
</h:form>
<h:panelGroup id="result" />
<h:form id="form">
<p:commandLink update=":result">
</h:form>
<h:panelGroup id="result" />
<h:form id="form">
<p:commandLink update=":result">
</h:form>
<h:form id="otherform">
<h:panelGroup id="result" />
</h:form>
<h:form id="form">
<p:commandLink update=":otherform:result">
</h:form>
<h:form id="otherform">
<h:panelGroup id="result" />
</h:form>
NamingContainer
komponen misalnya <h:form>
, <h:dataTable>
, <p:tabView>
, <cc:implementation>
(dengan demikian, semua komponen komposit), dll Anda mengenali mereka dengan mudah dengan melihat hasil HTML yang dihasilkan, ID mereka akan ditambahkan di ID klien yang dihasilkan dari semua komponen anak. Perhatikan bahwa jika mereka tidak memiliki ID tetap, JSF akan menggunakan ID yang dibuat secara otomatis dalam j_idXXX
format. Anda benar-benar harus menghindarinya dengan memberi mereka ID tetap. The OmniFacesNoAutoGeneratedIdViewHandler
dapat membantu dalam ini selama pengembangan.
Jika Anda mengetahui untuk menemukan javadoc dari yang UIComponent
dimaksud, maka Anda juga dapat memeriksa di sana apakah itu mengimplementasikan NamingContainer
antarmuka atau tidak. Misalnya, HtmlForm
( tag UIComponent
belakang <h:form>
) menunjukkan penerapannya NamingContainer
, tetapi HtmlPanelGroup
( tag UIComponent
belakang <h:panelGroup>
) tidak menampilkannya, jadi tidak diterapkan NamingContainer
. Berikut adalah javadoc dari semua komponen standar dan ini adalah javadoc dari PrimeFaces .
Memecahkan masalah Anda
Jadi dalam kasus Anda:
<p:tabView id="tabs">
<p:tab id="search">
<h:form id="insTable">
<p:dialog id="dlg">
<h:panelGrid id="display">
Output HTML yang dihasilkan <h:panelGrid id="display">
terlihat seperti ini:
<table id="tabs:insTable:display">
Anda harus menganggap itu id
sebagai ID klien dan kemudian mengawali dengan :
untuk penggunaan di update
:
<p:commandLink update=":tabs:insTable:display">
Mereferensikan di luar include / tagfile / composite
Jika tautan perintah ini ada di dalam include / tagfile, dan target berada di luarnya, dan dengan demikian Anda tidak perlu mengetahui ID dari induk penamaan penampung dari penampung penamaan saat ini, Anda dapat merujuknya secara dinamis melalui UIComponent#getNamingContainer()
seperti ini:
<p:commandLink update=":#{component.namingContainer.parent.namingContainer.clientId}:display">
Atau, jika tautan perintah ini ada di dalam komponen komposit dan target berada di luarnya:
<p:commandLink update=":#{cc.parent.namingContainer.clientId}:display">
Atau, jika tautan perintah dan target berada di dalam komponen komposit yang sama:
<p:commandLink update=":#{cc.clientId}:display">
Lihat juga Mendapatkan id wadah penamaan induk dalam template untuk atribut render / update
Bagaimana cara kerjanya di bawah selimut
Ini semua ditentukan sebagai "mencari ekspresi" di dalam UIComponent#findComponent()
javadoc :
Sebuah ekspresi pencarian terdiri dari baik identifier (yang cocok persis terhadap properti id dari UIComponent
, atau serangkaian pengenal tersebut terkait dengan UINamingContainer#getSeparatorChar
nilai karakter. Algoritma pencarian harus beroperasi sebagai berikut, meskipun alogrithms alternatif dapat digunakan selama hasil akhirnya sama:
- Identifikasi
UIComponent
yang akan menjadi basis pencarian, dengan berhenti segera setelah salah satu kondisi berikut terpenuhi:
- Jika ekspresi pencarian dimulai dengan karakter pemisah (disebut ekspresi pencarian "absolut"), basisnya akan menjadi akar
UIComponent
dari pohon komponen. Karakter pemisah utama akan dihilangkan, dan sisa ekspresi penelusuran akan diperlakukan sebagai ekspresi penelusuran "relatif" seperti yang dijelaskan di bawah ini.
- Kalau tidak, jika ini
UIComponent
adalah NamingContainer
itu akan menjadi dasar.
- Jika tidak, cari orang tua komponen ini. Jika
NamingContainer
ditemui, itu akan menjadi basis.
- Jika tidak (jika tidak
NamingContainer
ditemukan) root UIComponent
akan menjadi basis.
- Ekspresi pencarian (mungkin dimodifikasi pada langkah sebelumnya) sekarang menjadi ekspresi pencarian "relatif" yang akan digunakan untuk menemukan komponen (jika ada) yang memiliki id yang cocok, dalam lingkup komponen dasar. Pertandingan dilakukan sebagai berikut:
- Jika ekspresi penelusuran adalah pengenal sederhana, nilai ini dibandingkan dengan properti id, lalu secara rekursif melalui faset dan
UIComponent
turunan basis (kecuali jika turunan NamingContainer
ditemukan, faset dan turunannya sendiri tidak akan dicari).
- Jika ekspresi penelusuran menyertakan lebih dari satu pengenal yang dipisahkan oleh karakter pemisah, pengenal pertama digunakan untuk menemukan a
NamingContainer
menurut aturan di poin sebelumnya. Kemudian, findComponent()
metode ini NamingContainer
akan dipanggil, meneruskan sisa ekspresi pencarian.
Perhatikan bahwa PrimeFaces juga mengikuti spesifikasi JSF, tetapi RichFaces menggunakan "beberapa pengecualian tambahan" .
"reRender" menggunakan UIComponent.findComponent()
algoritme (dengan beberapa pengecualian tambahan) untuk menemukan komponen di pohon komponen.
Pengecualian tambahan tersebut tidak dijelaskan secara detail, tetapi diketahui bahwa ID komponen relatif (yaitu yang tidak dimulai dengan :
) tidak hanya dicari dalam konteks induk terdekat NamingContainer
, tetapi juga di semua NamingContainer
komponen lain dalam tampilan yang sama (yang relatif omong-omong, pekerjaan mahal).
Jangan pernah gunakan prependId="false"
Jika ini semua masih tidak berhasil, verifikasi jika Anda tidak menggunakan <h:form prependId="false">
. Ini akan gagal selama pemrosesan ajax submit dan render. Lihat juga pertanyaan terkait ini: UIForm dengan prependId = "false" break <f: ajax render> .
Mengacu pada putaran iterasi spesifik dari komponen iterasi
Sudah lama tidak mungkin untuk mereferensikan item iterasi tertentu dalam komponen iterasi seperti <ui:repeat>
dan <h:dataTable>
seperti ini:
<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>
Namun, sejak Mojarra 2.2.5 <f:ajax>
mulai mendukungnya (itu hanya berhenti memvalidasinya; sehingga Anda tidak akan pernah menghadapi pengecualian yang disebutkan dalam pertanyaan lagi; perbaikan peningkatan lain direncanakan untuk itu nanti).
Ini hanya tidak berfungsi di versi MyFaces 2.2.7 dan PrimeFaces 5.2 saat ini. Dukungan mungkin datang dalam versi yang akan datang. Sementara itu, taruhan terbaik Anda adalah memperbarui komponen iterasi itu sendiri, atau induk jika tidak merender HTML, seperti <ui:repeat>
.
Saat menggunakan PrimeFaces, pertimbangkan Ekspresi atau Pemilih Pencarian
Ekspresi Pencarian PrimeFaces memungkinkan Anda mereferensikan komponen melalui ekspresi pencarian pohon komponen JSF. JSF memiliki beberapa bawaan:
@this
: komponen saat ini
@form
: orang tua UIForm
@all
: seluruh dokumen
@none
: tidak ada
PrimeFaces telah menyempurnakan ini dengan kata kunci baru dan dukungan ekspresi komposit:
@parent
: komponen induk
@namingcontainer
: orang tua UINamingContainer
@widgetVar(name)
: komponen seperti yang diidentifikasi oleh yang diberikan widgetVar
Anda juga dapat mencampur kata kunci tersebut dalam ekspresi komposit seperti @form:@parent
, @this:@parent:@parent
, dll
PrimeFaces Selectors (PFS) seperti di @(.someclass)
memungkinkan Anda untuk mereferensikan komponen melalui sintaks pemilih CSS jQuery. Misalnya mereferensikan komponen yang memiliki semua kelas gaya umum dalam keluaran HTML. Ini sangat membantu jika Anda perlu merujuk "banyak" komponen. Ini hanya prasyarat bahwa komponen target memiliki semua ID klien dalam keluaran HTML (tetap atau dibuat otomatis, tidak masalah). Lihat juga Bagaimana PrimeFaces Selectors seperti di update = "@ (. MyClass)" bekerja?
context.getViewRoot().findComponent(":inputform" + UINamingContainer.getSeparatorChar(context) + "inputtext" );
Sertakan juga kode xhtml.prependId="false"
menyelamatkan hari saya.pertama-tama: sejauh yang saya tahu menempatkan dialog di dalam tabview adalah praktik yang buruk ... lebih baik Anda keluarkan ...
dan sekarang untuk pertanyaan Anda:
maaf, luangkan waktu untuk mendapatkan apa yang sebenarnya ingin Anda terapkan,
lakukan di aplikasi web saya sendiri sekarang, dan berhasil
seperti yang saya katakan sebelumnya, tempatkan p: dialog di luar `p: tabView,
tinggalkan dialog p: seperti yang Anda sarankan pada awalnya:
<p:dialog modal="true" widgetVar="dlg"> <h:panelGrid id="display"> <h:outputText value="Name:" /> <h:outputText value="#{instrumentBean.selectedInstrument.name}" /> </h:panelGrid> </p:dialog>
dan tautan perintah p: akan terlihat seperti ini (yang saya lakukan hanyalah mengubah atribut pembaruan)
<p:commandLink update="display" oncomplete="dlg.show()"> <f:setPropertyActionListener value="#{lndInstrument}" target="#{instrumentBean.selectedInstrument}" /> <h:outputText value="#{lndInstrument.name}" /> </p:commandLink>
hal yang sama berfungsi di aplikasi web saya, dan jika tidak berhasil untuk Anda, maka saya kira ada yang salah dalam kode kacang java Anda ...
sumber
Itu karena tab juga merupakan wadah penamaan ... pembaruan Anda harus
update="Search:insTable:display"
Apa yang dapat Anda lakukan juga adalah hanya menempatkan dialog Anda di luar formulir dan masih di dalam tab maka itu akan menjadi:update="Search:display"
sumber
Saya tahu ini sudah memiliki jawaban yang bagus oleh BalusC tetapi berikut adalah sedikit trik yang saya gunakan untuk mendapatkan wadah untuk memberi tahu saya clientId yang benar .
Berikut adalah contoh kode karena kata-kata saya mungkin tidak menggambarkannya dengan baik.
<p:tabView id="tabs"> <p:tab id="search" title="Search"> <h:form id="insTable"> <p:dataTable id="table" var="lndInstrument" value="#{instrumentBean.instruments}"> <p:column> <p:commandLink id="select"
Hapus pembaruan yang gagal dalam komponen ini
oncomplete="dlg.show()"> <f:setPropertyActionListener value="#{lndInstrument}" target="#{instrumentBean.selectedInstrument}" /> <h:outputText value="#{lndInstrument.name}" /> </p:commandLink> </p:column> </p:dataTable> <p:dialog id="dlg" modal="true" widgetVar="dlg"> <h:panelGrid id="display">
Tambahkan komponen di dalam komponen id yang Anda coba perbarui menggunakan pembaruan yang akan gagal
<p:commandButton id="BogusButton" update="BogusUpdate"></p:commandButton> <h:outputText value="Name:" /> <h:outputText value="#{instrumentBean.selectedInstrument.name}" /> </h:panelGrid> </p:dialog> </h:form> </p:tab> </p:tabView>
Buka halaman ini dan lihat kesalahannya. Kesalahannya adalah: javax.servlet.ServletException: Tidak dapat menemukan komponen untuk ekspresi "BogusUpdate" yang dirujuk dari tab: insTable: BogusButton
Jadi clientId yang benar untuk digunakan akan menjadi huruf tebal ditambah id dari wadah target (ditampilkan dalam kasus ini)
tabs:insTable:display
sumber
Coba ganti
update="insTable:display"
keupdate="display"
. Saya yakin Anda tidak dapat mengawali id dengan ID formulir seperti itu.sumber