<p:commandXxx process>
<p:ajax process>
<f:ajax execute>
process
Atrybut jest po stronie serwera, a może tylko wpłynąć UIComponent
s wykonawcze EditableValueHolder
(pól wejściowych) lub ActionSource
(pola poleceń). process
Atrybut mówi JSF, używając rozdzieloną spacjami listę identyfikatorów klienta, który dokładnie składniki muszą być przetwarzane przez cały cykl życia JSF po (częściowe) Forma przedstawienia.
Następnie JSF zastosuje wartości żądań (znajdując parametr żądania HTTP na podstawie własnego identyfikatora klienta komponentu, a następnie ustawiając go jako przesłaną wartość w przypadku EditableValueHolder
komponentów lub ustawiając w kolejce nowy ActionEvent
w przypadku ActionSource
komponentów), wykona konwersję, sprawdzenie poprawności i aktualizację wartości modelu ( EditableValueHolder
tylko komponenty) i wreszcie wywołaj kolejkę ActionEvent
( ActionSource
tylko komponenty). JSF pominie przetwarzanie wszystkich innych składników, które nie są objęte process
atrybutem. Również komponenty, których rendered
atrybut ocenia false
podczas fazy stosowania wartości żądań, zostaną również pominięte w ramach zabezpieczenia przed nieuprawnionymi żądaniami.
Zauważ, że w przypadku ActionSource
komponentów (takich jak <p:commandButton>
) bardzo ważne jest, abyś sam uwzględnił komponent w process
atrybucie, szczególnie jeśli zamierzasz wywołać akcję powiązaną z komponentem. Poniższy przykład, który zamierza przetwarzać tylko określone komponenty wejściowe po wywołaniu określonego komponentu polecenia, nie zadziała:
<p:inputText id="foo" value="#{bean.foo}" />
<p:commandButton process="foo" action="#{bean.action}" />
Byłoby przetwarzać tylko #{bean.foo}
i nie#{bean.action}
. Musisz także dołączyć sam komponent polecenia:
<p:inputText id="foo" value="#{bean.foo}" />
<p:commandButton process="@this foo" action="#{bean.action}" />
Lub, jak najwyraźniej się dowiedziałeś, używając, @parent
jeśli są to jedyne składniki mające wspólnego rodzica:
<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>
Lub, jeśli oba są jedynymi komponentami komponentu nadrzędnego UIForm
, możesz również użyć @form
:
<h:form>
<p:inputText id="foo" value="#{bean.foo}" />
<p:commandButton process="@form" action="#{bean.action}" />
</h:form>
Jest to czasami niepożądane, jeśli formularz zawiera więcej składników wejściowych, które chcesz pominąć w przetwarzaniu, częściej niż w przypadkach, gdy chcesz zaktualizować inne składniki wejściowe lub sekcję interfejsu użytkownika w oparciu o bieżący składnik wejściowy w metoda nasłuchująca ajax. Nie chcesz, aby błędy sprawdzania poprawności w innych komponentach wejściowych uniemożliwiały wykonanie metody nasłuchującej ajax.
Potem jest @all
. Nie ma to żadnego specjalnego efektu w process
atrybucie, ale tylko w update
atrybucie. process="@all"
Zachowuje się dokładnie tak samo jak process="@form"
. HTML i tak nie obsługuje przesyłania wielu formularzy jednocześnie.
Nawiasem mówiąc, istnieje również @none
, która może być przydatna w przypadku, gdy absolutnie nie trzeba niczego proces, ale tylko chcesz zaktualizować niektóre części konkretnych pośrednictwem update
, szczególnie te odcinki, których zawartość nie zależy od wartości lub słuchaczy złożonych działań.
Należy zauważyć, że process
atrybut nie ma wpływu na ładunek żądania HTTP (ilość parametrów żądania). Oznacza to, że <h:form>
nie będzie to miało wpływu na domyślne zachowanie HTML wysyłania „wszystkiego” zawartego w reprezentacji HTML pliku . Jeśli masz dużą formę i chcesz zmniejszyć ładunek żądania HTTP do tylko tych absolutnie niezbędnych w przetwarzaniu, tj. Tylko tych objętych process
atrybutem, możesz ustawić partialSubmit
atrybut w komponentach PrimeFaces Ajax jak w <p:commandXxx ... partialSubmit="true">
lub <p:ajax ... partialSubmit="true">
. Możesz również skonfigurować to „globalnie”, edytującweb.xml
i dodając
<context-param>
<param-name>primefaces.SUBMIT</param-name>
<param-value>partial</param-value>
</context-param>
Możesz także użyć <o:form>
OmniFaces 3.0+, który domyślnie zachowuje to zachowanie.
Standardowy JSF równoważny z właściwością PrimeFaces process
pochodzi execute
z <f:ajax execute>
. Zachowuje się dokładnie tak samo, z tym wyjątkiem, że nie obsługuje łańcucha rozdzielanego przecinkami, podczas gdy PrimeFaces taki (chociaż osobiście polecam po prostu trzymać się konwencji rozdzielonej spacjami), ani @parent
słowa kluczowego. Warto też wiedzieć, że <p:commandXxx process>
domyślnie jest @form
while <p:ajax process>
i <f:ajax execute>
domyślnie jest @this
. Na koniec warto również wiedzieć, że process
obsługuje tak zwane „selektory PrimeFaces”, zobacz także Jak działają selektory PrimeFaces jak w update = "@ (. MyClass)"?
<p:commandXxx update>
<p:ajax update>
<f:ajax render>
Ten update
atrybut jest po stronie klienta i może wpływać na reprezentację HTML wszystkichUIComponent
s. update
Atrybut mówi JavaScript (jeden odpowiedzialny za obsługę AJAX żądanie / odpowiedź), stosując rozdzieloną spacjami listę identyfikatorów klientów, które elementy w drzewie DOM HTML potrzebuje być aktualizowany jako odpowiedź do formy przedstawienia.
JSF przygotuje dla tego poprawną odpowiedź ajax, zawierającą tylko żądane części do aktualizacji. JSF pominie wszystkie inne komponenty, które nie są objęte update
atrybutem w odpowiedzi ajax, tym samym utrzymując niewielki ładunek odpowiedzi. Również komponenty, których rendered
atrybut ocenia false
podczas fazy odpowiedzi renderowania, zostaną pominięte. Zauważ, że nawet jeśli zwróci true
, JavaScript nie może zaktualizować go w drzewie HTML HTML, jeśli byłby początkowo false
. Zamiast tego musisz go owinąć lub zaktualizować jego element nadrzędny. Zobacz także Aktualizacja / renderowanie Ajax nie działa na komponencie, który wyrenderował atrybut .
Zwykle chcesz aktualizować tylko te komponenty, które naprawdę muszą zostać „odświeżone” po stronie klienta po (częściowym) przesłaniu formularza. Poniższy przykład aktualizuje cały formularz nadrzędny za pośrednictwem @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>
(zauważ, że process
atrybut jest pominięty, ponieważ domyślnie jest @form
już ustawiony )
Chociaż może to działać dobrze, aktualizacja komponentów wejściowych i poleceń jest w tym konkretnym przykładzie niepotrzebna. Jeśli nie zmienisz wartości modelu foo
i metody bar
wewnętrznej action
(co z kolei byłoby nieintuicyjne w perspektywie UX), nie ma sensu ich aktualizować. Składniki wiadomości są jedynymi, które naprawdę wymagają aktualizacji:
<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>
Jednak staje się to uciążliwe, gdy masz ich wiele. To jeden z powodów istnienia Selektorów PrimeFaces. Te komponenty wiadomości mają w wygenerowanym pliku wyjściowym HTML wspólną klasę stylów ui-message
, dlatego też należy wykonać następujące czynności:
<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>
(zwróć uwagę, że powinieneś zachować identyfikatory w komponentach wiadomości, w przeciwnym razie @(...)
nie zadziała! Ponownie zobacz, jak działają selektory PrimeFaces jak w update = "@ (. myClass)"? )
@parent
Aktualizuje tylko składnik nadrzędny, który tym samym obejmuje bieżącego składnika i wszystkie rodzeństwo i ich dzieci. Jest to bardziej przydatne, jeśli oddzieliłeś formularz w zdrowych grupach, a każda z nich ma własną odpowiedzialność. Te @this
aktualizacje, oczywiście, tylko obecny komponent. Zwykle jest to konieczne tylko wtedy, gdy trzeba zmienić jeden z własnych atrybutów HTML komponentu w metodzie akcji. Na przykład
<p:commandButton action="#{bean.action}" update="@this"
oncomplete="doSomething('#{bean.value}')" />
Wyobraź sobie, że oncomplete
trzeba pracować z tym, value
co zostało zmienione action
, a następnie ten konstrukt nie działałby, gdyby składnik nie został zaktualizowany, z prostego powodu, który oncomplete
jest częścią generowanego wyniku HTML (a zatem wszystkie wyrażenia EL są tam oceniane podczas renderowania odpowiedzi).
@all
Aktualizuje cały dokument, który powinien być stosowany z ostrożnością. Zwykle zamiast tego chcesz użyć prawdziwego żądania GET poprzez zwykły link ( <a>
lub <h:link>
) lub przekierowanie po POST przez ?faces-redirect=true
lub ExternalContext#redirect()
. W efektach process="@form" update="@all"
ma dokładnie taki sam efekt, jak przesłanie nie-ajaxowe (nie częściowe). W całej mojej karierze JSF jedynym sensownym przypadkiem użycia, na jaki się natknąłem, @all
jest wyświetlenie strony błędu w całości na wypadek wystąpienia wyjątku podczas żądania ajax. Zobacz także Jaki jest właściwy sposób postępowania z wyjątkami JSF 2.0 dla komponentów AJAXified?
Standardowy JSF równoważny z właściwością PrimeFaces update
pochodzi render
z <f:ajax render>
. Zachowuje się dokładnie tak samo, z tym wyjątkiem, że nie obsługuje łańcucha rozdzielanego przecinkami, podczas gdy PrimeFaces taki (chociaż osobiście polecam po prostu trzymać się konwencji rozdzielonej spacjami), ani @parent
słowa kluczowego. Zarówno domyślnie, jak update
i (czyli „nic”).render
@none
Zobacz też:
process
nie jest ustawione, więc używa domyślnej wartości@form
. Jest to również wyjaśnione w powyższej odpowiedzi.Jeśli masz trudności z zapamiętaniem wartości domyślnych (wiem, że mam ...), oto krótki fragment odpowiedzi BalusC:
źródło
process
dlap:commandXXX
to@all
. Ponadto wydaje się, że dotyczy to każdego komponentu obsługującego AJAX, takiego jakp:menuitem
.@all
? O ile mogę przeczytać odpowiedź BalusC, jest to@form
jednak@all
równoważne z@form
procesem. Dobra uwaga na temat innych komponentów, myślę, że będę musiał zajrzeć do kodu źródłowego, aby zobaczyć, do których komponentów się odnosi, ponieważ wolałbym nie pisać czegoś, co może być złe@all
kawałku. Musi wiedzieć, że niedawno ponownie wdrożył silnik AJAX PrimeFaces. Później dwukrotnie go sprawdziłem, ale czytałem kod źródłowy PrimeFaces i sprawdziłem żądania XHR. Mam nadzieję, że tym razem mam rację, ponieważ zaimplementowałem żądania AJAX BootsFaces, aby działały identycznie jak żądania AJAX PrimeFaces.Poprzez proces (w specyfikacji JSF nazywa się to execute) mówisz JSF, aby ograniczyło przetwarzanie do określonego komponentu, wszystko inne jest po prostu ignorowane.
Aktualizacja wskazuje, który element zostanie zaktualizowany, gdy serwer odpowie na Twoje żądanie.
@all : Każdy komponent jest przetwarzany / renderowany.
@this : Żądany komponent z atrybutem wykonania jest przetwarzany / renderowany.
@form : Formularz zawierający żądający komponent jest przetwarzany / renderowany.
@ rodzic: Element nadrzędny zawierający żądający komponent jest przetwarzany / renderowany.
Dzięki Primefaces możesz nawet używać selektorów JQuery, sprawdź tego bloga: http://blog.primefaces.org/?p=1867
źródło
Pamiętaj, że PrimeFaces obsługuje standardowe słowa kluczowe JSF 2.0+:
@this
Aktualny składnik.@all
Cały widok.@form
Najbliższa forma przodka bieżącego komponentu.@none
Bez komponentu.oraz standardowe słowa kluczowe JSF 2.3+:
@child(n)
n-te dziecko.@composite
Najbliższy przodek komponentu kompozytowego.@id(id)
Służy do wyszukiwania komponentów według ich identyfikatora, ignorując strukturę drzewa komponentów i nazywając kontenery.@namingcontainer
Najbliższy kontener nazewnictwa przodka bieżącego komponentu.@parent
Nadrzędny bieżącego komponentu.@previous
Poprzednie rodzeństwo.@next
Następne rodzeństwo.@root
Instancji UIViewRoot widoku można użyć do rozpoczęcia wyszukiwania od katalogu głównego zamiast bieżącego komponentu.Ale zawiera także niektóre słowa kluczowe specyficzne dla PrimeFaces:
@row(n)
n-ty rząd.@widgetVar(name)
Komponent z podanym widgetVar.I możesz nawet użyć czegoś o nazwie „PrimeFaces Selectors”, co pozwala na użycie jQuery Selector API. Na przykład, aby przetworzyć wszystkie dane wejściowe w elemencie z klasą CSS
myClass
:Widzieć:
źródło