<p:commandXxx process>
<p:ajax process>
<f:ajax execute>
Các process
thuộc tính là phía máy chủ và chỉ có thể ảnh hưởng đến UIComponent
s thực hiện EditableValueHolder
(trường đầu vào) hoặc ActionSource
(trường lệnh). Các process
thuộc tính nói với JSF, sử dụng một danh sách không gian tách ID khách hàng, trong đó thành phần chính xác phải được xử lý thông qua toàn bộ vòng đời JSF thuận (một phần) hình thức nộp.
Sau đó, JSF sẽ áp dụng các giá trị yêu cầu (tìm tham số yêu cầu HTTP dựa trên ID khách hàng của thành phần và sau đó đặt nó làm giá trị đã gửi trong trường hợp EditableValueHolder
thành phần hoặc xếp hàng mới ActionEvent
trong trường hợp ActionSource
thành phần), thực hiện chuyển đổi, xác thực và cập nhật giá trị mô hình ( EditableValueHolder
chỉ các thành phần) và cuối cùng gọi ra hàng đợi ActionEvent
( ActionSource
chỉ các thành phần). JSF sẽ bỏ qua việc xử lý tất cả các thành phần khác không process
thuộc tính. Ngoài ra, các thành phần có rendered
thuộc tính ước tính false
trong giai đoạn áp dụng giá trị yêu cầu cũng sẽ bị bỏ qua như một phần của biện pháp bảo vệ chống lại các yêu cầu giả mạo.
Lưu ý rằng trong trường hợp các ActionSource
thành phần (chẳng hạn <p:commandButton>
) rất quan trọng, bạn cũng bao gồm chính thành phần đó trong process
thuộc tính, đặc biệt nếu bạn có ý định gọi hành động liên quan đến thành phần đó. Vì vậy, ví dụ dưới đây dự định chỉ xử lý (các) thành phần đầu vào nhất định khi một thành phần lệnh nhất định được gọi sẽ không hoạt động:
<p:inputText id="foo" value="#{bean.foo}" />
<p:commandButton process="foo" action="#{bean.action}" />
Nó sẽ chỉ xử lý #{bean.foo}
và không sự #{bean.action}
. Bạn cũng cần bao gồm chính thành phần lệnh:
<p:inputText id="foo" value="#{bean.foo}" />
<p:commandButton process="@this foo" action="#{bean.action}" />
Hoặc, như bạn rõ ràng đã phát hiện ra, sử dụng @parent
nếu chúng là thành phần duy nhất có cha mẹ chung:
<p:panel><!-- Type doesn't matter, as long as it's a common parent. -->
<p:inputText id="foo" value="#{bean.foo}" />
<p:commandButton process="@parent" action="#{bean.action}" />
</p:panel>
Hoặc, nếu cả hai tình cờ là thành phần duy nhất của UIForm
thành phần cha mẹ , thì bạn cũng có thể sử dụng @form
:
<h:form>
<p:inputText id="foo" value="#{bean.foo}" />
<p:commandButton process="@form" action="#{bean.action}" />
</h:form>
Điều này đôi khi không mong muốn nếu biểu mẫu chứa nhiều thành phần đầu vào mà bạn muốn bỏ qua trong quá trình xử lý, thường xuyên hơn trong trường hợp khi bạn muốn cập nhật (các) thành phần đầu vào khác hoặc một số giao diện người dùng dựa trên thành phần đầu vào hiện tại trong một phương pháp nghe ajax. Cụ thể là bạn không muốn các lỗi xác thực trên các thành phần đầu vào khác đang ngăn phương thức nghe ajax được thực thi.
Sau đó, có @all
. Điều này không có tác dụng đặc biệt trong process
thuộc tính, mà chỉ trong update
thuộc tính. Một process="@all"
hành vi giống hệt như process="@form"
. HTML không hỗ trợ gửi nhiều biểu mẫu cùng một lúc.
Nhân tiện, cũng @none
có thể hữu ích trong trường hợp bạn hoàn toàn không cần xử lý bất cứ điều gì, mà chỉ muốn cập nhật một số phần cụ thể thông qua update
, đặc biệt là những phần có nội dung không phụ thuộc vào giá trị được gửi hoặc người nghe hành động.
Cần lưu ý rằng process
thuộc tính không có ảnh hưởng đến tải trọng yêu cầu HTTP (số lượng tham số yêu cầu). Có nghĩa là, hành vi HTML mặc định gửi "mọi thứ" có trong biểu diễn HTML của <h:form>
sẽ không bị ảnh hưởng. Trong trường hợp bạn có một biểu mẫu lớn và muốn giảm tải trọng yêu cầu HTTP xuống chỉ những điều này thực sự cần thiết trong xử lý, tức là chỉ những process
thuộc tính này được bao phủ bởi thuộc tính, thì bạn có thể đặt partialSubmit
thuộc tính trong các thành phần PrimeFaces Ajax như trong <p:commandXxx ... partialSubmit="true">
hoặc <p:ajax ... partialSubmit="true">
. Bạn cũng có thể định cấu hình 'toàn cầu' này bằng cách chỉnh sửa web.xml
và thêm
<context-param>
<param-name>primefaces.SUBMIT</param-name>
<param-value>partial</param-value>
</context-param>
Ngoài ra, bạn cũng có thể sử dụng <o:form>
OmniFaces 3.0+, mặc định cho hành vi này.
JSF tiêu chuẩn tương đương với PrimeFaces cụ thể process
là execute
từ <f:ajax execute>
. Nó hoạt động giống hệt nhau ngoại trừ việc nó không hỗ trợ chuỗi được phân tách bằng dấu phẩy trong khi PrimeFaces thực hiện (mặc dù cá nhân tôi khuyên bạn chỉ nên sử dụng quy ước được phân tách bằng dấu cách), cũng không phải @parent
từ khóa. Ngoài ra, có thể hữu ích khi biết rằng <p:commandXxx process>
mặc định @form
trong khi <p:ajax process>
và <f:ajax execute>
mặc định là @this
. Cuối cùng, cũng hữu ích khi biết rằng process
hỗ trợ cái gọi là "Bộ chọn PrimeFaces", xem thêm Bộ chọn PrimeFaces như trong update = "@ (. MyClass)" hoạt động như thế nào?
<p:commandXxx update>
<p:ajax update>
<f:ajax render>
Các update
thuộc tính là phía khách hàng và có thể ảnh hưởng đến các đại diện HTML của tất cả các UIComponent
s. Các update
thuộc tính nói với JavaScript (một trong những trách nhiệm xử lý các yêu cầu ajax / response), sử dụng một danh sách không gian tách ID khách hàng, phần nào trong cây cần HTML DOM để được cập nhật khi đối phó với các hình thức nộp.
Sau đó, JSF sẽ chuẩn bị phản hồi ajax đúng cho điều đó, chỉ chứa các phần được yêu cầu để cập nhật. JSF sẽ bỏ qua tất cả các thành phần khác không được update
thuộc tính trong phản hồi ajax, theo đó giữ cho trọng tải phản hồi nhỏ. Ngoài ra, các thành phần có rendered
thuộc tính ước tính false
trong giai đoạn phản hồi kết xuất sẽ bị bỏ qua. Lưu ý rằng ngay cả khi nó trả về true
, JavaScript không thể cập nhật nó trong cây DOM HTML nếu ban đầu false
. Thay vào đó, bạn cần phải bọc nó hoặc cập nhật cha mẹ của nó. Xem thêm Cập nhật / kết xuất Ajax không hoạt động trên một thành phần có thuộc tính kết xuất .
Thông thường, bạn muốn cập nhật chỉ những thành phần mà thực sự cần phải được "làm mới" ở phía client trên (một phần) hình thức nộp. Ví dụ dưới đây cập nhật toàn bộ biểu mẫu gốc thông qua @form
:
<h:form>
<p:inputText id="foo" value="#{bean.foo}" required="true" />
<p:message id="foo_m" for="foo" />
<p:inputText id="bar" value="#{bean.bar}" required="true" />
<p:message id="bar_m" for="bar" />
<p:commandButton action="#{bean.action}" update="@form" />
</h:form>
(lưu ý rằng process
thuộc tính được bỏ qua vì mặc định @form
đã có)
Trong khi điều đó có thể hoạt động tốt, việc cập nhật các thành phần đầu vào và lệnh trong ví dụ cụ thể này là không cần thiết. Trừ khi bạn thay đổi các giá trị mô hình foo
và phương thức bar
bên trong action
(điều này sẽ không trực quan trong phối cảnh UX), không có điểm nào cập nhật chúng. Các thành phần thông báo là thứ duy nhất thực sự cần được cập nhật:
<h:form>
<p:inputText id="foo" value="#{bean.foo}" required="true" />
<p:message id="foo_m" for="foo" />
<p:inputText id="bar" value="#{bean.bar}" required="true" />
<p:message id="bar_m" for="bar" />
<p:commandButton action="#{bean.action}" update="foo_m bar_m" />
</h:form>
Tuy nhiên, điều đó trở nên tẻ nhạt khi bạn có nhiều người trong số họ. Đó là một trong những lý do khiến PrimeFaces Selector tồn tại. Các thành phần thông báo này có trong đầu ra HTML được tạo một lớp kiểu chung ui-message
, do đó, những điều sau đây cũng nên làm:
<h:form>
<p:inputText id="foo" value="#{bean.foo}" required="true" />
<p:message id="foo_m" for="foo" />
<p:inputText id="bar" value="#{bean.bar}" required="true" />
<p:message id="bar_m" for="bar" />
<p:commandButton action="#{bean.action}" update="@(.ui-message)" />
</h:form>
(lưu ý rằng bạn nên giữ ID trên các thành phần thông báo, nếu không @(...)
sẽ không hoạt động! Một lần nữa, hãy xem Cách chọn PrimeFaces như trong update = "@ (. myClass)" để biết chi tiết)
Các @parent
bản cập nhật chỉ có thành phần cha mẹ, do đó bao gồm thành phần hiện tại và tất cả anh chị em và con cái của họ. Điều này hữu ích hơn nếu bạn đã tách biểu mẫu trong các nhóm lành mạnh với mỗi trách nhiệm riêng của mình. Các @this
bản cập nhật, rõ ràng, chỉ có thành phần hiện tại. Thông thường, điều này chỉ cần thiết khi bạn cần thay đổi một trong các thuộc tính HTML của chính thành phần trong phương thức hành động. Ví dụ
<p:commandButton action="#{bean.action}" update="@this"
oncomplete="doSomething('#{bean.value}')" />
Hãy tưởng tượng rằng các oncomplete
nhu cầu để làm việc với cái value
đã được thay đổi action
, thì cấu trúc này sẽ không hoạt động nếu thành phần không được cập nhật, vì lý do đơn giản oncomplete
là một phần của đầu ra HTML được tạo (và do đó tất cả các biểu thức EL trong đó được đánh giá trong quá trình trả lời kết xuất).
Các @all
cập nhật toàn bộ tài liệu, cần được sử dụng cẩn thận. Thông thường, bạn muốn sử dụng một yêu cầu GET thực sự cho việc này thay vì bằng một liên kết đơn giản ( <a>
hoặc <h:link>
) hoặc chuyển hướng sau khi POST bằng ?faces-redirect=true
hoặc ExternalContext#redirect()
. Trong các hiệu ứng, process="@form" update="@all"
có chính xác hiệu ứng tương tự như một lần gửi không phải là ajax (không phải một phần). Trong toàn bộ sự nghiệp JSF của tôi, trường hợp sử dụng hợp lý duy nhất tôi gặp phải @all
là hiển thị toàn bộ trang lỗi trong trường hợp có ngoại lệ xảy ra trong yêu cầu ajax. Xem thêm Cách chính xác để xử lý các ngoại lệ JSF 2.0 cho các thành phần AJAXified là gì?
JSF tiêu chuẩn tương đương với PrimeFaces cụ thể update
là render
từ <f:ajax render>
. Nó hoạt động giống hệt nhau ngoại trừ việc nó không hỗ trợ chuỗi được phân tách bằng dấu phẩy trong khi PrimeFaces thực hiện (mặc dù cá nhân tôi khuyên bạn chỉ nên sử dụng quy ước được phân tách bằng dấu cách), cũng không phải @parent
từ khóa. Cả hai update
và render
mặc định là @none
(không có gì ").
Xem thêm: