Tìm trong đầu ra HTML cho ID khách hàng thực tế
Bạn cần xem xét đầu ra HTML đã tạo để tìm ID khách hàng phù hợp. Mở trang trong trình duyệt, nhấp chuột phải và Xem Nguồn . Xác định vị trí đại diện HTML của thành phần JSF quan tâm và lấy nó id
làm ID khách hàng. Bạn có thể sử dụng nó một cách tuyệt đối hoặc tương đối tùy thuộc vào vùng chứa tên hiện tại. Xem chương sau.
Lưu ý: nếu nó có chứa chỉ số lặp như :0:
, :1:
v.v. (vì nó nằm trong thành phần lặp), thì bạn cần nhận ra rằng việc cập nhật một vòng lặp cụ thể không phải lúc nào cũng được hỗ trợ. Xem dưới cùng của câu trả lời để biết thêm chi tiết về điều đó.
Ghi nhớ NamingContainer
các thành phần và luôn cung cấp cho chúng một ID cố định
Nếu một thành phần mà bạn muốn tham chiếu theo quy trình ajax / thực thi / cập nhật / kết xuất nằm trong cùng một NamingContainer
cha mẹ, thì chỉ cần tham chiếu ID của chính nó.
<h:form id="form">
<p:commandLink update="result"> <!-- OK! -->
<h:panelGroup id="result" />
</h:form>
Nếu nó không giống nhau NamingContainer
, thì bạn cần tham chiếu nó bằng ID khách hàng tuyệt đối. ID khách hàng tuyệt đối bắt đầu bằng NamingContainer
ký tự phân cách, theo mặc định :
.
<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
thành phần là ví dụ <h:form>
, <h:dataTable>
, <p:tabView>
, <cc:implementation>
(do đó, tất cả các thành phần composite), vv Bạn có nhận ra chúng một cách dễ dàng bằng cách nhìn vào đầu ra HTML được tạo ra, ID của họ sẽ được thêm vào phía trước ID khách hàng tạo của tất cả các thành phần con. Lưu ý rằng khi họ không có ID cố định, thì JSF sẽ sử dụng ID được tạo tự động theo j_idXXX
định dạng. Bạn tuyệt đối nên tránh điều đó bằng cách cung cấp cho họ một ID cố định. Các OmniFacesNoAutoGeneratedIdViewHandler
có thể hữu ích trong việc này trong thời gian phát triển.
Nếu bạn biết để tìm javadoc của UIComponent
câu hỏi, thì bạn cũng có thể kiểm tra xem nó có thực hiện NamingContainer
giao diện hay không. Ví dụ: HtmlForm
( thẻ UIComponent
phía sau <h:form>
) hiển thị nó thực hiện NamingContainer
, nhưng HtmlPanelGroup
( thẻ UIComponent
phía sau <h:panelGroup>
) không hiển thị, vì vậy nó không thực hiện NamingContainer
. Đây là javadoc của tất cả các thành phần tiêu chuẩn và đây là javadoc của PrimeFaces .
Giải quyết vấn đề của bạn
Vì vậy, trong trường hợp của bạn về:
<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">
Đầu ra HTML được tạo ra <h:panelGrid id="display">
trông như thế này:
<table id="tabs:insTable:display">
Bạn cần lấy chính xác đó id
là ID khách hàng và sau đó là tiền tố :
để sử dụng trong update
:
<p:commandLink update=":tabs:insTable:display">
Tham chiếu bên ngoài bao gồm / tagfile / composite
Nếu liên kết lệnh này nằm trong tệp bao gồm / tagfile và mục tiêu nằm ngoài nó, và do đó bạn không nhất thiết phải biết ID của bộ chứa tên đặt tên của bộ chứa đặt tên hiện tại, thì bạn có thể tự động tham chiếu nó qua UIComponent#getNamingContainer()
như vậy:
<p:commandLink update=":#{component.namingContainer.parent.namingContainer.clientId}:display">
Hoặc, nếu liên kết lệnh này nằm trong một thành phần hỗn hợp và mục tiêu nằm ngoài nó:
<p:commandLink update=":#{cc.parent.namingContainer.clientId}:display">
Hoặc, nếu cả liên kết lệnh và đích nằm trong cùng một thành phần hỗn hợp:
<p:commandLink update=":#{cc.clientId}:display">
Xem thêm Nhận id của thùng chứa đặt tên cha mẹ trong mẫu cho thuộc tính kết xuất / cập nhật
Làm thế nào nó hoạt động dưới vỏ bọc
Điều này tất cả được xác định là "tìm kiếm cụm từ" trong các UIComponent#findComponent()
javadoc :
Một biểu hiện tìm kiếm bao gồm hoặc là một định danh (mà là lần xuất hiện chính xác đối với các tài sản id của một UIComponent
, hoặc một loạt các mã nhận dạng đó được liên kết bởi các UINamingContainer#getSeparatorChar
giá trị nhân vật. Các thuật toán tìm kiếm nên hoạt động như sau, mặc dù alogrithms thay thế có thể được sử dụng miễn là kết quả cuối cùng là như nhau:
- Xác định
UIComponent
đó sẽ là cơ sở để tìm kiếm, bằng cách dừng ngay khi một trong các điều kiện sau được đáp ứng:
- Nếu biểu thức tìm kiếm bắt đầu bằng ký tự dấu tách (được gọi là biểu thức tìm kiếm "tuyệt đối"), cơ sở sẽ là gốc
UIComponent
của cây thành phần. Ký tự phân cách hàng đầu sẽ bị loại bỏ và phần còn lại của biểu thức tìm kiếm sẽ được coi là biểu thức tìm kiếm "tương đối" như được mô tả bên dưới.
- Mặt khác, nếu đây
UIComponent
là một NamingContainer
nó sẽ phục vụ như là cơ sở.
- Nếu không, tìm kiếm cha mẹ của thành phần này. Nếu a
NamingContainer
gặp phải, nó sẽ là cơ sở.
- Mặt khác (nếu không
NamingContainer
gặp phải) gốc UIComponent
sẽ là cơ sở.
- Biểu thức tìm kiếm (có thể được sửa đổi trong bước trước) bây giờ là biểu thức tìm kiếm "tương đối" sẽ được sử dụng để định vị thành phần (nếu có) có id khớp với, trong phạm vi của thành phần cơ sở. Trận đấu được thực hiện như sau:
- Nếu biểu thức tìm kiếm là một định danh đơn giản, giá trị này được so sánh với thuộc tính id và sau đó đệ quy thông qua các khía cạnh và con của cơ sở
UIComponent
(ngoại trừ nếu NamingContainer
tìm thấy hậu duệ , các khía cạnh và con riêng của nó không được tìm kiếm).
- Nếu biểu thức tìm kiếm bao gồm nhiều hơn một mã định danh được phân tách bằng ký tự phân tách, mã định danh đầu tiên được sử dụng để xác định vị trí
NamingContainer
theo quy tắc trong điểm đầu dòng trước đó. Sau đó, findComponent()
phương thức này NamingContainer
sẽ được gọi, chuyển phần còn lại của biểu thức tìm kiếm.
Lưu ý rằng PrimeFaces cũng tuân thủ thông số JSF, nhưng RichFaces sử dụng "một số ngoại lệ bổ sung" .
"reRender" sử dụng UIComponent.findComponent()
thuật toán (với một số ngoại lệ bổ sung) để tìm thành phần trong cây thành phần.
Các ngoại lệ bổ sung đó không được mô tả chi tiết, nhưng được biết rằng ID thành phần tương đối (nghĩa là các ID không bắt đầu :
) không chỉ được tìm kiếm trong ngữ cảnh của cha mẹ gần nhất NamingContainer
, mà còn trong tất cả các NamingContainer
thành phần khác trong cùng một chế độ xem (tương đối Nhân tiện công việc đắt tiền).
Không bao giờ sử dụng prependId="false"
Nếu tất cả điều này vẫn không hoạt động, sau đó xác minh nếu bạn không sử dụng <h:form prependId="false">
. Điều này sẽ thất bại trong quá trình xử lý ajax gửi và kết xuất. Xem thêm câu hỏi liên quan này: UIForm với preendId = "false" break <f: ajax render> .
Tham khảo vòng lặp cụ thể của các thành phần lặp
Đã từ lâu không thể tham chiếu một mục lặp cụ thể trong các thành phần lặp như thế <ui:repeat>
và <h:dataTable>
như vậy:
<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>
Tuy nhiên, vì Mojarra 2.2.5 đã <f:ajax>
bắt đầu hỗ trợ nó (đơn giản là nó đã dừng xác nhận nó; do đó bạn sẽ không bao giờ phải đối mặt với ngoại lệ trong câu hỏi được đề cập nữa; một sửa chữa nâng cao khác được lên kế hoạch cho lần sau).
Điều này chỉ không hoạt động trong các phiên bản MyFaces 2.2.7 và PrimeFaces 5.2 hiện tại. Sự hỗ trợ có thể đến trong các phiên bản trong tương lai. Trong khi đó, cách tốt nhất của bạn là cập nhật chính thành phần lặp hoặc cha mẹ trong trường hợp nó không hiển thị HTML, như thế nào <ui:repeat>
.
Khi sử dụng PrimeFaces, hãy xem xét Biểu thức tìm kiếm hoặc Bộ chọn
Biểu thức tìm kiếm PrimeFaces cho phép bạn tham chiếu các thành phần thông qua các biểu thức tìm kiếm cây thành phần JSF. JSF có một số nội dung:
@this
: thành phần hiện tại
@form
: cha mẹ UIForm
@all
: toàn bộ tài liệu
@none
: không có gì
PrimeFaces đã tăng cường điều này với các từ khóa mới và hỗ trợ biểu thức tổng hợp:
@parent
: thành phần cha mẹ
@namingcontainer
: cha mẹ UINamingContainer
@widgetVar(name)
: thành phần như được xác định bởi đã cho widgetVar
Bạn cũng có thể kết hợp các từ khóa trong các biểu thức tổng hợp như @form:@parent
, @this:@parent:@parent
vv
PrimeFaces Selector (PFS) như trong @(.someclass)
cho phép bạn tham chiếu các thành phần thông qua cú pháp bộ chọn CSS jQuery. Ví dụ: các thành phần tham chiếu có tất cả một lớp kiểu chung trong đầu ra HTML. Điều này đặc biệt hữu ích trong trường hợp bạn cần tham khảo "rất nhiều" thành phần. Điều này chỉ yêu cầu các thành phần đích có tất cả ID khách trong đầu ra HTML (cố định hoặc tự động, không thành vấn đề). Xem thêm Làm thế nào để các bộ chọn PrimeFaces như trong update = "@ (. MyClass)" hoạt động?