SORU
27 Temmuz 2010, Salı


JSTL JSF2 Facelets... mantıklı?

Facelets bit bir kod koşullu olarak çıkış yapmak istiyorum.

Bu amaçla, JSTL etiketleri iyi çalışmıyor gibi görünüyor:

<c:if test="${lpc.verbose}">
    ...
</c:if>

Ancak, bu en iyi yöntem ise emin değilim? Benim hedefe ulaşmak için başka bir yol var mı?

CEVAP
27 Temmuz 2010, Salı


Giriş

JSTL <c:xxx> etiketler taghandlers ve sırasında yürütülürgörünüm oluşturma, AKSARAY <h:xxx> etiketler UI components ve sırasında yürütülüroluşturma zamanı.

AKSARAY kendi <f:xxx> <ui:xxx> sadece bu etiketleri unutmayındeğilUIComponent uzatmak da, , *, <ui:define>*22 21*örneğin*, vb taghandlers. UIComponent uzatmak olanlar da OLUMSUZLUK UI bileşenleri, *, <ui:repeat>*26 25*örneğin*, vb. Ayrıca, AKSARAY UI bileşenleri id binding özniteliklerini görüntülemek boyunca inşa değerlendirilir. Böylece aşağıda cevabını onlar için de geçerlidir.

Görünümü zaman XHTML/JSP dosyasının ayrıştırılması ve daha sonra FacesContext UIViewRoot olarak depolanan AKSARAY bileşeni bir ağaç dönüştürüldüğünde şu an inşa. Görünüm oluşturma zaman OLUMSUZLUK bileşen ağaç HTML oluşturmak için UIViewRoot#encodeAll() ile başlayan üzereyken o an. Yani: bileşenleri ve JSTL etiketleri kodlama beklediğiniz gibi senkronize çalışmaz AKSARAY UI. Aşağıdaki gibi görselleştirebilirsiniz JSTL ilk, AKSARAY bileşen ağacı üreten, AKSARAY sırası yukarıdan aşağıya doğru çalıştırmak için yine yukarıdan aşağıya, HTML çıktı üreten çalışır.

<c:forEach> vs <ui:repeat>

Örneğin, bu işaretleme 3 öğe <c:forEach> kullanarak yineleme Facelets:

<c:forEach items="#{bean.items}" var="item">
    <h:outputText id="item_#{item.id}" value="#{item.value}" />
</c:forEach>

...görünüm sırasında oluşturur zaman inşa AKSARAY bileşen ağacında <h:outputText> üç ayrı bileşenleri, kabaca bu şekilde temsil:

<h:outputText id="item_1" value="#{bean.items[0].value}" />
<h:outputText id="item_2" value="#{bean.items[1].value}" />
<h:outputText id="item_3" value="#{bean.items[2].value}" />

sırayla tek tek görüntüleme sırasında HTML çıktılarını oluşturma zamanı üreten:...

<span id="item_1">value1</span>
<span id="item_2">value2</span>
<span id="item_3">value3</span>

El ile bileşen Kimliği teklik sağlamak için gerekir ve bu da derleme zamanı sırasında görünümü değerlendirilir unutmayın.

Bu 3 ürün üzerinde işaretleme yineleme AKSARAY UI bileşeni olan <ui:repeat> kullanarak Facelets süre:

<ui:repeat id="items" value="#{bean.items}" var="item">
    <h:outputText id="item" value="#{item.value}" />
</ui:repeat>

...aynı <h:outputText> bileşen görünümü sırasında sayede zaten olduğu gibi AKSARAY bileşen ağacında biter render olma zamanıyenidenHTML çıktısı geçerli yineleme yuvarlak temel oluşturmak için:

<span id="items:0:item">value1</span>
<span id="items:1:item">value2</span>
<span id="items:2:item">value3</span>

Not <ui:repeat> olarak NamingContainer bileşen zaten temin teklik istemci KİMLİĞİ dayalı yineleme dizin; bu da mümkün olmadığı için kullanma EL id öznitelik bu şekilde de değerlendirilmesi sırasında görünüm oluşturmak zaman ise #{item} yalnızca sırasında render süresi.

*/*49<c:if> vs rendered

Başka bir örnek olarak, bu biçimlendirme koşullu olarak farklı etiketler <c:if> kullanarak (ayrıca bu <c:choose><c:when><c:otherwise> kullanabilirsiniz) ekleme Facelets:

<c:if test="#{field.type eq 'TEXT'}">
    <h:inputText ... />
</c:if>
<c:if test="#{field.type eq 'PASSWORD'}">
    <h:inputSecret ... />
</c:if>
<c:if test="#{field.type eq 'SELECTONE'}">
    <h:selectOneMenu ... />
</c:if>

...type = TEXT durumunda OLUMSUZLUK bileşen ağacına: <h:inputText> bileşen katacak

<h:inputText ... />

Bu işaretleme Facelets süre:

<h:inputText ... rendered="#{field.type eq 'TEXT'}" />
<h:inputSecret ... rendered="#{field.type eq 'PASSWORD'}" />
<h:selectOneMenu ... rendered="#{field.type eq 'SELECTONE'}" />

...AKSARAY bileşen ağaç durumu ne olursa olsun tam olarak yukarıdaki gibi. Bu olabilir, böylece sonunda bir "şişirilmiş" bileşen ağacı ne zaman pek çok kişinin onları ve onlar aslında temel bir "statik" modeli (yani field değil hiç değişim sırasında en az görünüm kapsamı).

<c:set> vs <ui:param>

Bunlar değiştirilebilir değil. <c:set> erişilebilir olan EL kapsamda bir değişken ayarlarsonragörüntüleme sırasında etiket konum zaman, ama her yerde görünüm sırasında render zamanında inşa. <ui:param> Facelet bir şablon <ui:include>, <ui:decorate template> <ui:composition template>) dahil EL bir değişken geçirir. AKSARAY eski sürümleri <ui:param> değişkeni de söz konusu Facelet şablon dışında kullanılabilir, bu asla güvenilmemelidir sayede böcekler vardı.

scope niteliği olmayan <c:set> takma isim gibi davranır. Herhangi bir kapsamda önbellek EL ifadenin sonucu değildir. Böylece gayet iyi örneğin AKSARAY bileşenleri yineleme içinde kullanılabilir. Böylece, örneğin aşağıda iyi çalışır:

<c:set var="totalPrice" value="#{0}" />
<ui:repeat value="#{bean.products}" var="product">
    <c:set var="totalPrice" value="#{totalPrice   product.price}" />
    ...
</ui:repeat>
<p>Total price: #{totalPrice}</p>

Not: EL 3.0 beri bu özel durum için: simpler approach bir şey var

<ui:repeat value="#{bean.products}" var="product">
    ...
</ui:repeat>
<p>Total price: #{bean.products.stream().map(product->product.price).sum()}</p>

Sadece, zaman ayarlama scope öznitelik ile izin verilen değerler request, view, session, ya application, o zaman değerlendirilir derhal sırasında görünüm oluşturmak zaman ve saklı belirtilen kapsam.

<c:set var="dev" value="#{facesContext.application.projectStage eq 'Development'}" scope="application" />

Bu sadece bir kez ve tüm uygulama boyunca #{dev} olarak kullanılabilir değerlendirilecektir.

JSTL AKSARAY bileşen ağacı bina kontrol etmek için kullanın

JSTL kullanarak, tek bir kurşun beklenmeyen sonuçlar olarak içinde OLUMSUZLUK yineleme bileşenleri gibi <h:dataTable>, <ui:repeat>, vb, ya da ne zaman JSTL tag öznitelikleri bağlı sonuçlar OLUMSUZLUK olayları gibi preRenderView veya gönderilen form değerleri model olan değil mevcut görüntüleme sırasında inşa zaman.

Ayrıca, mojarra bağlamda sürümleri 2.1.18 daha eski JSTL etiket niteliğini kısmi bir devlet görünümü fasulye kapsamlı başvururken kaydedilirken bir hata oluştu. Tüm görünüm fasulye olurdu kapsamlıyeniyeniden görünümü yerine ağaç sadece tam görünüm ağaç henüz JSTL çalışır noktasında müsait değil çünkü () alınır. Eğer beklediğin veya saklamadan bir devlet görünümü kapsamlı bean tarafından bir JSTL tag niteliği değişmeyecek o zaman dönüş değeri beklersiniz, ya da olacak "lost" gerçek görünüm kapsamı bean hangisi restore sonra görünümü ağaç kurdu.

Özetle: AKSARAY bileşen ağacı binanın akışını kontrol etmek için Kullanın JSTL etiketleri. AKSARAY UI bileşenleri HTML çıktısı nesil akışını kontrol etmek için kullanın. AKSARAY bileşenler etiket nitelikleri JSTL için yineleme var bağlamaz. JSTL tag öznitelikleri AKSARAY olayları güvenmeyin. En azından mojarra bağlamda 2.1.18 tavuk-yumurta sorunu manzaralı kapsam tamir için kullanın, aksi takdirde web.xml kısmi koruma durumuna kapatmak gerekir.

<context-param>
    <param-name>javax.faces.PARTIAL_STATE_SAVING</param-name>
    <param-value>false</param-value>
</context-param>

Ayrıca Bkz:

JSTL etiketleri yararlı (gerçekten düzgün görünümüne bina boyunca kullanıldığında yani) bazı gerçek dünya örnekleri görmek için cevaplar/şu sorulara bakın:


Özetle

Somut işlevsel bir gereği olarak, eğer istersenizkılıyorAKSARAY bileşenleri koşullu olarak, OLUMSUZLUK HTML bileşeni rendered özniteliği kullanınözellikle#{lpc} <h:dataTable> <ui:repeat> gibi OLUMSUZLUK yineleme bir bileşen şu anda yinelenen öğeyi temsil eder.

<h:someComponent rendered="#{lpc.verbose}">
    ...
</h:someComponent>

Ya da, eğer istersenizinşa(Ekle/oluştur) bileşenleri şartlı AKSARAY, JSTL kullanmaya devam o zaman. Yol verbosely new SomeComponent() java yaptığını çok daha iyi.

<c:if test="#{lpc.verbose}">
    <h:someComponent>
        ...
    </h:someComponent>
</c:if>

Ayrıca Bkz:

Bunu Paylaş:
  • Google+
  • E-Posta
Etiketler:

YORUMLAR

SPONSOR VİDEO

Rastgele Yazarlar

  • Bratayley

    Bratayley

    30 Aralık 2010
  • CaptainDisillusion

    CaptainDisil

    18 EYLÜL 2007
  • InfinityWard

    InfinityWard

    19 EYLÜL 2006