new SelectItem(Title.MISS, "Miss");
在JSF 2.0之前使用SelectItems通常很繁瑣,因為您需要編寫代碼以使域對象適應SelectItems 。 JSF 2.0進行了很多改進,您現在可以使用EL表達式動態構造SelectItems 。 例如:
<h:selectOneMenu><f:selectItems value="#{customerRepository.all}" var="customer" label="#{customer.name}"/>
</h:selectOneMenu>
這無疑有助于減少樣板代碼的數量,但是,我仍然認為我們可以做一些事情使SelectItems更加易于使用,尤其是在使用Spring時。 考慮到這一點,我一直在開發<s:selectItems>組件,旨在代替<f:selectItems> 。
我們可以做的第一件事是通過消除指定var屬性的需要來幫助減少樣板的鍵入。 使用<s:selectItems>時 ,如果未指定var屬性,則默認為item 。 所以上面的代碼可以寫成:
<h:selectOneMenu><s:selectItems value="#{customerRepository.all}" label="#{item.name}"/>
</h:selectOneMenu>
在上面的示例中,該值綁定到一個存儲庫接口,該接口返回“ 客戶”實體集合 。 與標準<f:selectItems>組件一樣,您也可以綁定到Array或DataModel 。 此外,新組件還支持任何以逗號分隔的String值。
<h:selectOneMenu><s:selectItems value="Java, Spring, JavaServer Faces"/>
</h:selectOneMenu>
<s:selectItems>可以幫助的下一件事是空值。 在下拉菜單中需要一個“ Please Select”選項來表示null是很常見的。 在原始JSF中,這通常可能意味著每個組件都需要額外加價:
<h:selectOneMenu><f:selectItem label="--- Please Select ---" noSelectionOption="true" itemValue=""/><s:selectItems value="'{items}"/>
</h:selectOneMenu>
無需為每個元素添加額外的標記,只要將其鏈接到UISelectOne組件,我們的組件就會自動插入“請選擇”選項。 您可以使用includeNoSelectionOption屬性來覆蓋此行為。 用于“不選擇選項”的標簽將默認為“-請選擇-”,但是您可以通過在您的ApplicationContext中添加一個org.springframework.context.MessageSource來解析和修改代碼“ spring.faces” ,從而輕松自定義和國際化此文本。 .noselectionoption” 。
在MessageSource的主題上, <s:selectItems>組件將盡可能嘗試使用org.springframework.springfaces.message.ObjectMessageSource創建SelectItem的標簽。 我過去在博客中寫過有關如何將對象轉換為消息的內容,而該組件只是利用了這些想法。
在創建要顯示的SelectItem時,新組件對我們有所幫助,但是如何處理表單提交呢? 如何將提交的String選項轉換回真實對象 ? 在上面的第一個示例中,我們綁定到JPA 客戶實體; 值將顯示得很好,但是當您提交表單時,將顯示“轉換錯誤”,因為JSF不知道如何從提交的String返回到Customer對象。 通常的答案是開發自己的javax.faces.convert.Converter實現,但這通常是有問題的。 通常,您選擇的項目值將是一些復雜的對象,很難完整地表示為String 。
編寫將與UISelectOne或UISelectMany組件一起使用的Converter時,可以使用一種有趣的技術。 實際上,您只需要編寫代碼就可以從Object轉換為String ,則可以通過迭代SelectItem并返回單個Object值(轉換為String時與您提交的值匹配)來完成從另一個方向的轉換。 您可以在 Arjan Tijms的此博客文章中了解有關此想法的更多信息。 將此技術與<s:selectItems>組件一起使用非常簡單,只需提供一個itemConverterStringValue屬性,該屬性將用于創建唯一的getAsString()值:
<h:selectOneMenu><s:selectItems value="#{customerRepository.all}" label="#{item.name}" itemConverterStringValue="#{item.id}"/>
</h:selectOneMenu>
實際上, itemConverterStringValue是可選的。 如果未指定,則將使用對象的toString()方法;對于JPA @Entity ,將自動使用@ID字段。 如果需要,您仍然可以自由編寫和附加自己的Converter,在這種情況下, itemConverterStringValue將被忽略。
最后,這是<s:selectItems>可以執行的另一個技巧。 如果選擇組件綁定到布爾值或枚舉,則可以完全省略value屬性。 選擇項將基于綁定支持的所有可能選項( 布爾值“是” /“否”或完整的枚舉值集)構建。 這也適用于類型化的集合。 例如,以下將顯示選項“ Java”,“ Spring”和“ JavaServer Faces”(假設您具有適當的ObjectMessageSource ):
public enum Technology {JAVA, SPRING, JAVASERVER_FACES
}
public class Bean implements Serializable {private Set<Technology> technologies = new HashSet<Technology>();// ... getters and setters
}
<h:selectManyCheckbox value="#{bean.technologies}"><s:selectItems/>
</h:selectManyCheckbox>
參考: 集成Spring和JavaServer Faces:從Phil Webb博客博客中的JCG合作伙伴 Phillip Webb 選擇項目 。
翻譯自: https://www.javacodegeeks.com/2012/06/spring-jsf-integration-select-items.html