这种实现方式挺奇怪,但是也确实不错。
其tml核心部分为:
<t:form t:id="locale"> <img src="${asset:images/country.png}" /> ① <br /> <input t:type="select" model="LocalesSource" ② encoder="localeEncoder" ③ validate="required" value="selectedLocale" ④ onchange="this.form.submit();" /> </t:form>
① 记住格式,没有_zh什么的。但是我们的images/country_zh.png需要放到和该tml相同的目录下。
② 这要注意一下,因为select组件是一个比较特殊的组件,它的model的类型必须是SelectModel类型。至于这个类型怎么生成看java代码。
③ 只要select的value不是一个string类型的,就需要给他提供一个encoder
④ 这个地方的关注主要看java代码。。。
还有最后一点儿,就是这个onchange要是一个submit,只有这样才能够把我们的locale传递到后台。。。
java部分如下:
public class LocaleSwitcher {
// 这里取出来的就是Application Module中设定的SymbolConstants.SUPPORTED_LOCALES的值 @Inject @Property @Symbol(SymbolConstants.SUPPORTED_LOCALES) private String locales;
// 这里应该是核心,它能够帮助我们完成Locale的持久化。 @Inject private PersistentLocale persistentLocale;
// SelectModel的生成器。。。 @Inject private SelectModelFactory selectModelFactory;
// 这里是用来把前端传递过来的locale设定给我们tml中的value,而且同时设定给tapestry,让他帮我们管理 public void setSelectedLocale(Locale locale) { persistentLocale.set(locale); } // 这里就能够把设定给tapestry的locale取出来赋给我们的locale public Locale getSelectedLocale() { return persistentLocale.get(); }
// 获得select的source public SelectModel getLocalesSource() { String[] countrys = locales.split(","); List<Locale> localeList = new ArrayList<Locale>(); for (String country : countrys) { localeList.add(new Locale(country)); } // 后面的这个字符串displayLanguage,需要是list里面包含的对象的一个属性。 return selectModelFactory.create(localeList, "displayLanguage"); }
// 设定Encoder
// 就是实现ValueEncoder接口,有一个toClient和一个toValue.
// toClient 通过后台的V返回一个字符串显示给页面。
// toValue 通过前台的value生成一个V给后台。 public ValueEncoder<Locale> getLocaleEncoder() { return new ValueEncoder<Locale>() { public String toClient(Locale locale) { return locale.getLanguage(); } public Locale toValue(String language) { return new Locale(language); } }; } }
这样就完成了全部。效果图: