PrimeFaces işlemini / güncellemesini ve JSF f: ajax yürütme / oluşturma niteliklerini anlama


194

Tam olarak nedir processve updatePrimeFaces içinde p:commandXxxbileşenleri ve executeve renderiçinde f:ajaxetiketi?

Doğrulama sırasında hangisi çalışır? updateÖznitelik, değeri arka uçtan bileşene güncellemek yerine ne yapar ? Do processmodele nitelik bağlamak değeri? Tam olarak ne yapıyoruz @this, @parent, @allve @formher iki özniteliklerde?

Aşağıdaki örnek iyi çalışıyor, ancak temel kavramlar konusunda biraz kafam karıştı.

<p:commandButton process="@parent"
                 update="@form"
                 action="#{bean.submit}" 
                 value="Submit" />

Yanıtlar:


307

<p:commandXxx process> <p:ajax process> <f:ajax execute>

processNitelik sunucu tarafı ve sadece etkileyebilir UIComponentuygulayan s EditableValueHolder(giriş alanları) veya ActionSource(komut alanları). processÖzelliği, bileşenlerin tam olarak üzerine tüm MTU yaşam döngüsü boyunca işlenmesi gereken müşteri kimlikleri, bir boşluk ile ayrılmış listesini kullanarak, JSF söyler (kısmi) formunda göndermek.

JSF daha sonra istek değerlerini uygular (bileşenin kendi istemci kimliğine göre HTTP istek parametresini bulur ve ardından EditableValueHolderbileşenler durumunda gönderilen değer olarak ayarlar veya bileşenler ActionEventdurumunda yeni bir kuyruk ActionSourceoluşturur), dönüştürme, doğrulama ve model değerlerini güncelleme ( EditableValueHolderyalnızca bileşenler) ve son olarak kuyruğa alınanları çağırır ActionEvent( ActionSourceyalnızca bileşenler). JSF, processöznitelik kapsamında olmayan diğer tüm bileşenlerin işlenmesini atlayacaktır . Ayrıca, başvuru istek değerleri aşamasında renderedözniteliği değerlendirilen bileşenler falsede kurcalanmış isteklere karşı korumanın bir parçası olarak atlanacaktır.

Şu nedenlerden dolayı olduğunu Not ActionSource(örneğin bileşenler <p:commandButton>de bileşenin kendisini dahil olması çok önemlidir) processEğer bileşeni ile ilişkili işlemi çağırmak niyetinde, özellikle öznitelik. Bu nedenle, belirli bir komut bileşeni çağrıldığında yalnızca belirli giriş bileşenlerini işlemeyi amaçlayan aşağıdaki örnek çalışmaz:

<p:inputText id="foo" value="#{bean.foo}" />
<p:commandButton process="foo" action="#{bean.action}" />

Sadece işlemek olur #{bean.foo}ve değil#{bean.action} . Komut bileşeninin kendisini de eklemeniz gerekir:

<p:inputText id="foo" value="#{bean.foo}" />
<p:commandButton process="@this foo" action="#{bean.action}" />

Ya da, görünüşe göre, @parentortak bir ebeveyne sahip olan tek bileşen olup olmadıklarını kullanarak :

<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>

Veya, her ikisi de ana UIFormbileşenin tek bileşenleri olursa , şunları da kullanabilirsiniz @form:

<h:form>
    <p:inputText id="foo" value="#{bean.foo}" />
    <p:commandButton process="@form" action="#{bean.action}" />
</h:form>

Formda, işlemde atlamak istediğiniz daha fazla girdi bileşeni varsa, başka bir girdi bileşenini veya geçerli girdi bileşenini temel alan bir UI bölümünü güncellemek istediğinizden daha sık bu bazen istenmeyen bir durumdur. ajax dinleyici yöntemi. Diğer giriş bileşenlerindeki doğrulama hatalarının ajax dinleyici yönteminin yürütülmesini engellemesini istemezsiniz.

Sonra @all. Bunun processözellikte özel bir etkisi yoktur , sadece updateözellikte vardır. A process="@all"tam olarak aynı şekilde davranır process="@form". HTML zaten aynı anda birden çok form göndermeyi desteklemiyor.

Bu arada @none, kesinlikle hiçbir şey işlemeniz gerekmemesi durumunda yararlı olabilecek bir de vardır, ancak yalnızca belirli bölümleri update, özellikle içeriği gönderilen değerlere veya eylem dinleyicilerine bağlı olmayan bölümler aracılığıyla güncellemek istersiniz .

Gibi olmalıdır kaydeden processöznitelik vardır bir HTTP isteği bilgisi (istek parametrelerinin miktarı) üzerinde etki. Yani, HTML temsilini içeren "her şeyi" gönderme varsayılan HTML davranışı <h:form>etkilenmez. Büyük bir formunuz varsa ve HTTP isteği yükünü yalnızca işlemede kesinlikle gerekli olanlara, yani yalnızca processöznitelik kapsamında olanlara azaltmak istiyorsanız , partialSubmitözniteliği PrimeFaces Ajax bileşenlerinde <p:commandXxx ... partialSubmit="true">veya olarak ayarlayabilirsiniz <p:ajax ... partialSubmit="true">. Bu 'global olarak' düzenleyerek web.xmlve ekleyerek de yapılandırabilirsiniz.

<context-param>
    <param-name>primefaces.SUBMIT</param-name>
    <param-value>partial</param-value>
</context-param>

Alternatif olarak, <o:form>bu davranışı varsayılan OmniFaces 3.0+ kullanabilirsiniz .

PrimeFaces spesifik standart MTU eşdeğer processolduğunu executeden <f:ajax execute>. PrimeFaces'ın yaptığı gibi virgülle ayrılmış bir dizeyi desteklememesi dışında tamamen aynı şekilde davranır (kişisel olarak yalnızca boşlukla ayrılmış konvansiyona sadık kalmayı öneririm) veya @parentanahtar kelime. Ayrıca, <p:commandXxx process>varsayılan olarak @formwhile <p:ajax process>ve <f:ajax execute>varsayılan olarak bilmek yararlı olabilir @this. Son olarak, process"PrimeFaces Seçicileri" olarak adlandırılanları desteklediğini bilmek de yararlıdır , ayrıca bkz. PrimeFaces Seçicileri update = "@ (. MyClass)" daki gibi nasıl çalışır?


<p:commandXxx update> <p:ajax update> <f:ajax render>

updateNitelik istemci tarafı ve tüm HTML sunumunu etkileyebilir UIComponents. updateNitelik JavaScript söyler, HTML DOM ağacı muhtaç parçalar forma göndermek için tepki olarak güncellenmesine müşteri kimlikleri, bir boşlukla ayrılmış listesini kullanarak (ajax isteği / tepkisini işlemek için sorumlu bir).

JSF daha sonra yalnızca güncellenmesi istenen parçaları içeren doğru ajax yanıtını hazırlayacaktır . JSF update, ajax yanıtında özniteliğin kapsamadığı diğer tüm bileşenleri atlayarak yanıt yükünü küçük tutar. Ayrıca, oluşturma yanıtı aşamasında renderedniteliği değerlendirilen bileşenler falseatlanacaktır. Geri dönmesine rağmen trueJavaScript'in başlangıçta HTML DOM ağacında güncelleyemeyeceğini unutmayın false. Bunun yerine sarmanız veya üst öğesini güncellemeniz gerekir. Ayrıca bkz. Ajax güncelleme / render özelliği oluşturulan bir bileşen üzerinde çalışmaz .

Genellikle, yalnızca (kısmi) form gönderildikten sonra istemci tarafında gerçekten "yenilenmesi" gereken bileşenleri güncellemek istersiniz . Aşağıdaki örnek, üst formun tamamını şu şekilde günceller @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>

( processözelliğin @formzaten varsayılan olarak atlandığını unutmayın )

Bu işe yarayabilse de, giriş ve komut bileşenlerinin güncellenmesi bu örnekte gereksizdir. Model değerlerini foove barinside actionyöntemini değiştirmediğiniz sürece (bu da UX perspektifinde sezgisel olmayacaktır), bunları güncellemenin bir anlamı yoktur. Mesaj bileşenleri gerçekten güncellenmesi gereken bileşenlerdir :

<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>

Ancak, birçoğunuz olduğunda bu sıkıcı olur. PrimeFaces Seçicilerinin var olmasının nedenlerinden biri de budur. Bu ileti bileşenleri, oluşturulan HTML çıktısında ortak bir stil sınıfına sahiptir ui-message, bu nedenle aşağıdakiler de yapılmalıdır:

<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>

(kimlikleri ileti bileşenlerinde tutmanız gerektiğini unutmayın, aksi takdirde @(...)çalışmaz! Yine, bkz. PrimeFaces Seçicileri update = "@ (. myClass)" daki gibi nasıl çalışır? ayrıntılar için)

@parentBöylece cari bileşeni ve tüm kardeşleri ve çocukları kapsayan tek ebeveyn bileşeni, günceller. Formu aklı başında gruplar halinde kendi sorumlulukları ile ayırdıysanız, bu daha yararlıdır. @thisGüncellemeler, belli ki, sadece mevcut bileşeni. Normalde, bu yalnızca bileşenin eylem yöntemindeki kendi HTML özelliklerinden birini değiştirmeniz gerektiğinde gereklidir. Örneğin

<p:commandButton action="#{bean.action}" update="@this" 
    oncomplete="doSomething('#{bean.value}')" />

Üzerinde değişiklik oncompleteyapılan çalışma ihtiyaçlarının , bileşen güncellenmezse, bu yapının , oluşturulan HTML çıktısının bir parçası olan basit bir nedenden dolayı işe yaramayacağını düşünün (ve buradaki tüm EL ifadeleri değerlendirilir. render yanıtı sırasında).valueactiononcomplete

@allDikkatle kullanılması gereken belgenin tamamını, günceller. Normalde, bunun yerine bir düz bağlantı (ya bu için gerçek bir GET isteğinde kullanmak istiyorum <a>ya <h:link>) ya da bir yönlendirme-sonra-POST ?faces-redirect=trueveya ExternalContext#redirect(). Efektlerde, process="@form" update="@all"ajax olmayan (kısmi olmayan) bir gönderme ile tamamen aynı etkiye sahiptir. Tüm JSF kariyerim boyunca, karşılaştığım tek mantıklı kullanım durumu @all, bir ajax isteği sırasında istisna olması durumunda bir hata sayfasını bütünüyle görüntülemektir. Ayrıca bkz . AJAXified bileşenleri için JSF 2.0 özel durumlarıyla başa çıkmanın doğru yolu nedir?

PrimeFaces spesifik standart MTU eşdeğer updateolduğunu renderden <f:ajax render>. PrimeFaces'ın yaptığı gibi virgülle ayrılmış bir dizeyi desteklememesi dışında tamamen aynı şekilde davranır (kişisel olarak yalnızca boşlukla ayrılmış konvansiyona sadık kalmayı öneririm) veya @parentanahtar kelime. Hem updateve rendervarsayılan olarak @none(yani, "hiçbir şey").


Ayrıca bakınız:


Güncelleme = "" kullandığımda, destek fasulyesinin yönetilen özelliği ayarlanmaz ve @PostConstruct rutinim başarısız olur. Düşüncesi olan var mı? DÜZENLEME: • Sonraki POST isteklerinde # {param} yönetilen bir özelliğine güveniyorsanız, bunu UICommand bileşenlerine <f: param> olarak eklemeniz gerekir.
K.Nicholas

panelGroup'un bir işlemi / güncellemesi bu panelGroup'un içeriğini işleyebilir / güncelleyebilir ex: <h: panelGroup id = "pgId"> // girdi metinleri buraya girer <h: panelGroup> <p: commandLink process = "pgId" güncellemesi = "pgId" />
bob-cac

Thx @BalusC Bu çok güzel açıklama için!
ProgrammingIsAwsome

2
@Rapster: processayarlanmadığından, varsayılan değerini kullanır @form. Bu ayrıca yukarıdaki cevapta da açıklanmaktadır.
BalusC

2
@Roland: Uygulama yapılandırmasında farklı, daha ciddi bir sorunu gizliyor.
BalusC

54

Varsayılan değerleri hatırlamakta zorlanıyorsanız (sahip olduğumu biliyorum ...) BalusC'ın cevabından kısa bir alıntı:

Bileşen | Gönder | Yenile
------------ | --------------- | --------------
f: ajax | execute = "@ this" | işlemek = "none @"
p: ajax | süreç = "@ this" | update = "@ none"
p: komutXXX | süreç = "@ form" | update = "@ none"

Sadece küçük bir düzeltme: varsayılan değeri processiçin p:commandXXXise @all. Ayrıca, bu AJAX'ı destekleyen her bileşen için geçerli gibi görünüyor p:menuitem.
Stephan Rauh

1
Merhaba @StephanRauh, yorumunuz için çok teşekkürler. Varsayılanı nerede okudunuz @all? Bildiğim kadarıyla öyle BalusC cevabı okuyabilir olarak @form, ancak @alleşdeğerdir @formsürecinde. Diğer bileşenler hakkında iyi bir nokta, sanırım yanlış olabilecek bir şey yazmayı tercih etmeyeceğim için, hangi bileşenlere uygulandığını görmek için kaynak koduna
bakmam gerekecek

1
@ JaqenH'ghar Thomas Andraschko bana @allbiraz bahsetti . Son zamanlarda PrimeFaces'in AJAX motorunu yeniden uyguladığını bilmeli. Daha sonra, iki kez kontrol ettim ama PrimeFaces kaynak kodunu okudum ve XHR isteklerine bakarak. Umarım bu sefer doğru anladım çünkü BootsFaces'in AJAX isteklerini PrimeFaces'in AJAX istekleriyle aynı şekilde çalışmak için uyguladım.
Stephan Rauh

HTML birden çok formun gönderilmesini desteklemediğinde varsayılanın @all olduğunu söylemek yanıltıcı olacaktır. Geliştiricilerin etkin varsayılan değeri bilmesi gerekir (böylece Thomas buna göre değişebilir). Bu arada, bu varsayılanlar Primefaces Kullanıcı Kılavuzu 6.2'de null olarak yanlış tanımlanmıştır.
Marc Dzaebel

27

İşlemle (JSF belirtiminde yürütme olarak adlandırılır) JSF'ye işlemi, yalnızca göz ardı edilen her şeyin belirtilen bileşenle sınırlamasını söylersiniz.

güncelleme, sunucu isteğinize yanıt verdiğinde hangi öğenin güncelleneceğini gösterir.

@all : Her bileşen işlenir / işlenir.

@this : execute özelliğine sahip istekte bulunan bileşen işlenir / işlenir.

@form : İstekte bulunan bileşeni içeren form işlenir / işlenir.

@parent : İstekte bulunan bileşeni içeren üst öğe işlenir / işlenir.

Primefaces ile JQuery seçicileri bile kullanabilirsiniz, şu bloga göz atın: http://blog.primefaces.org/?p=1867


2

PrimeFaces'in standart JSF 2.0+ anahtar kelimelerini desteklediğini lütfen unutmayın:

  • @this Geçerli bileşen.
  • @all Tüm görünüm.
  • @form Geçerli bileşenin en yakın ata biçimi.
  • @none Bileşen yok.

ve standart JSF 2.3+ anahtar kelimeleri:

  • @child(n) nci çocuk.
  • @composite En yakın kompozit bileşen atası.
  • @id(id) Bileşen ağacı yapısını ve adlandırma kaplarını yoksayarak bileşenlerini kimlikleriyle aramak için kullanılır.
  • @namingcontainer Geçerli bileşenin en yakın ata adlandırma kapsayıcısı.
  • @parent Geçerli bileşenin üst öğesi.
  • @previous Önceki kardeş.
  • @next Sonraki kardeş.
  • @root Görünümün UIViewRoot örneği, geçerli bileşen yerine kökten aramaya başlamak için kullanılabilir.

Ancak, bazı PrimeFaces'e özgü anahtar kelimelerle birlikte gelir:

  • @row(n) n. satır.
  • @widgetVar(name) Verilen widgetVar ile bileşen.

Ve jQuery Seçici API'sini kullanmanıza izin veren "PrimeFaces Selectors" adlı bir şey bile kullanabilirsiniz. Örneğin, bir öğedeki tüm girdileri CSS sınıfıyla işlemek için myClass:

process="@(.myClass :input)"

Görmek:


2
JSF2.3 + 'in bile anahtar kelimelerin çoğunu desteklediğini unutmayın.
tandraschko
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.