首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 软件管理 > 软件架构设计 >

【通译】Wicket启示录——理论与实践(三)完

2012-11-09 
【翻译】Wicket启示录——理论与实践(三)完接下来,我们再看看EditContact类,把新建联系人的话和编辑联系人也给

【翻译】Wicket启示录——理论与实践(三)完

接下来,我们再看看EditContact类,把新建联系人的话和编辑联系人也给实现了,开始吧:

?

public class EditContact extends BasePage {

??? public EditContact() {
??????? setModel(new CompoundPropertyModel(new LoadableDetachableModel() {
??????????? protected Object load() {
??????????????? return new Contact();
??????????? }
??????? }));
??????? init();
??? }

??? public EditContact(final Long contactId) {
??????? setModel(new CompoundPropertyModel(new LoadableDetachableModel() {
??????????? protected Object load() {
??????????????? return WicketApplication.get().getContactDao().get(contactId);
??????????? }
??????? }));
??????? init();
??? }

??? private void init() {
??????? add(new FeedbackPanel("feedback"));
??????? add(new ContactForm("form", getModel()));
??? }

??? private class ContactForm extends Form {

??????? public ContactForm(String id, IModel m) {
??????????? super(id, m);

??????????? TextField firstName = new TextField("firstName");
??????????? firstName.setRequired(true);
??????????? firstName.add(StringValidator.maximumLength(15));
??????????? add(firstName);

??????????? TextField lastName = new TextField("lastName");
??????????? lastName.setRequired(true);
??????????? lastName.add(StringValidator.maximumLength(20));
??????????? add(lastName);

??????????? TextField email = new TextField("email");
??????????? email.add(StringValidator.maximumLength(150));
??????????? email.add(EmailAddressValidator.getInstance());
??????????? add(email);

??????????? TextArea notes = new TextArea("notes");
??????????? notes.add(StringValidator.maximumLength(500));
??????????? add(notes);

??????????? DropDownChoice group = new DropDownChoice("group");
??????????? group.setChoices(new AbstractReadOnlyModel() {
??????????????? public Object getObject() {
??????????????????? List<String> l = new ArrayList<String>(3);
??????????????????? l.add("Friend");
??????????????????? l.add("Co-Worker");
??????????????????? l.add("Nemesis");
??????????????????? return l;
??????????????? }
??????????? });
??????????? add(group);

??????????? add(new Button("save") {
??????????????? public void onSubmit() {
??????????????????? Contact c = (Contact) getForm().getModelObject();
??????????????????? WicketApplication.get().getContactDao().save(c);
??????????????????? setResponsePage(ListContacts.class);
??????????????? }
??????????? });
??????????? add(new Button("cancel") {
??????????????? public void onSubmit() {
??????????????????? setResponsePage(ListContacts.class);
??????????????? }
??????????? }.setDefaultFormProcessing(false));
??????? }
??? }
}

?

EditContact类的两个构造函数就可以搞定编辑功能。第一个构造函数不带任何参数,目的是用来创建一个新的联系人。即使是新建一个新实体,这里我们仍然可以使用LoadableDetachableModel类来返回一个new Contact。因为当page存储在PageMap中时,LoadableDetachableModel会确保CompoundPropertyModel不去serialize (序列化)一个数据库中不存在的对象。因此,在这里对要新建的对象设置一些默认值是非常不错的选择,比如我们可以对Contact设置一个默认的Group。

?

第二个构造函数将Contact的主键id作为参数,从数据库读取该对象后,进行相应的编辑操作。构造函数里还调用了init()方法。该方法很简单,加入了一个FeedbackPanel组件,并且将得到的Contact模型绑定到Form上去。FeedbackPanel是Wicket的一个消息反馈组件,比如说如果用户没有输入用户名,那么后台就会将错误信息通过它来显示到前台页面上。用法与其它组件一样,在markup文件标记下:

?

?

<span wicket:id="feedback"></span>

?

?

任何验证错误信息都可以通过HTML的<span>元素显示出来.你可以反馈你更希望使用什么风格显示你的错误信息,但那是后话了.

?

看看Contact的firstName属性所对应的TextField组件设置:

?

TextField firstName = new TextField("firstName");
firstName.setRequired(true);
firstName.add(StringValidator.maximumLength(15));
add(firstName);

?

看到了吗,我们在这里设置了Contact的firstName属性所对应的TextField输入的字符串长度不能超过15.别的组件也用了类似的验证,原理是一样的.最后还有一个需要注意的组件是DropDownChoice.它专门用来显示HTML的select元素.在我们的例子中,通过使用DropDownChoice的setChoices()方法将我们Contact的group属性列表值显示在HTML上了:

?

?

DropDownChoice group = new DropDownChoice("group");
group.setChoices(new AbstractReadOnlyModel() {
??? public Object getObject() {
??????? List<String> l = new ArrayList<String>(3);
??????? l.add("Friend");
??????? l.add("Co-Worker");
??????? l.add("Nemesis");
??????? return l;
??? }
});

?

?

?

上面代码中用到的AbstractReadOnlyModel也是IModel的实现之一,将返回的String列表填充到select元素的option中去,生成的HTML片断如下:

?

?

<select>
??? <option value="Friend">Friend</option>
??? <option value="Co-Worker">Co-Worker</option>
??? <option value="Nemesis">Nemesis</option>
</select>

?

?

?

上的例子有点简单,其实DropDownChoice在IChoiceRenderer的帮助下,也可以支持很丰富的自定义对象,那么我也演示一下吧:

?

?

public class Group {
??? private String name;

??? public Group(String name) {
??????? setName(name);
??? }

??? public String getName() {
??????? return name;
??? }

??? public void setName(String name) {
??????? this.name = name;
??? }

}?

?

?

?

好的,我们将原来的代码改动一下,请注意看下面:

?

DropDownChoice group = new DropDownChoice("group");
group.setChoices(new AbstractReadOnlyModel() {
??? public Object getObject() {
??????? List<Group> l = new ArrayList<Group>(3);
??????? l.add(new Group("Friend"));
??????? l.add(new Group("Co-Worker"));
??????? l.add(new Group("Nemesis"));
??????? return l;
??? }
});
group.setChoiceRenderer(new IChoiceRenderer() {
??? public Object getDisplayValue(Object o) {
??????? Group g = (Group) o;
??????? return g.getName();
??? }
??? public String getIdValue(Object o) {
??????? Group g = (Group) o;
??????? return g.getName();
??? }
});

?

IChoiceRenderer接口允许开发人员决定select元素的option中text,value属性分别是什么.如果你先前用过其它web框架的select元素列表,你会发现Wicket做的比其它都要棒。

?

最后是两个Button组件:

?

?


add(new Button("save") {
??? public void onSubmit() {
??????? Contact c = (Contact) getForm().getModelObject();
??????? WicketApplication.get().getContactDao().save(c);
??????? setResponsePage(ListContacts.class);
??? }
});
add(new Button("cancel") {
??? public void onSubmit() {
??????? setResponsePage(ListContacts.class);
??? }
}.setDefaultFormProcessing(false));

?

?

第一个button是用来保存contact模型后跳转到ListContacts页面.第二个button是用来取消对contact模型的编辑,直接跳转回ListContacts页面.两个button的不同之处在于,除了两个不同的onSubmit()行为事件外,还对cancel button调用setDefaultFormProcessing(false)方法,这样当单击cancel button后,不会执行Form体代码,即上述那些验证,更新Contact模型的操作全部跳过,直接返回ListContacts页面.当单击submit button后,Wicket会经过以下几个步骤:

?

l???????? 进行输入验证

l???????? 如果输入有效,就将输入值更新相应的模型对象.

l???????? 执行onSubmit()方法.

?

?

如果你不想处更新型对象,不想进行什么验证.那好,为你的form加上一个cancel button,非常简单,不需要什么复杂的逻辑处理.

?

EditContact类也看完了,最后再看一遍相应的markup文件.这一回,你再看markup文件,应该不吃力了吧:

?

<wicket:extend>
??? <span wicket:id="feedback"></span>

??? <form wicket:id="form">
??????? <div id="contacts">
??????????? <div type="text"/>
??????????????????????? </td>
??????????????????? </tr>
??????????????????? <tr>
??????????????????????? <td>
??????????????????????????? Last Name
??????????????????????? </td>
??????????????????????? <td>
??????????????????????????? <input wicket:id="lastName" type="text"/>
??????????????????????? </td>
??????????????????? </tr>
??????????????????? <tr>
??????????????????????? <td>
??????????????????????????? Email
??????????????????????? </td>
??????????????????????? <td>
??????????????????????????? <input wicket:id="email" type="text" size="40"/>
??????????????????????? </td>
??????????????????? </tr>
??????????????????? <tr>
??????????????????????? <td>
??????????????????????????? Notes
??????????????????????? </td>
??????????????????????? <td>
??????????????????????????? <textarea wicket:id="notes" rows="4" cols="40"></textarea>
??????????????????????? </td>
??????????????????? </tr>
??????????????????? <tr>
??????????????????????? <td>
??????????????????????????? Group
??????????????????????? </td>
??????????????????????? <td>
??????????????????????????? <select wicket:id="group"> </select>
??????????????????????? </td>
??????????????????? </tr>
??????????????????? <tr>
??????????????????????? <td colspan="3" align="center">
??????????????????????????? <input wicket:id="save" type="submit" value="Save"/>
??????????????????????????? <input wicket:id="cancel" type="submit" value="Cancel"/>
??????????????????????? </td>
??????????????????? </tr>
??????????????? </table>
??????????? </div>
??????? </div>
??? </form>
</wicket:extend>

?

?

wicket:id属性加上HTML元素就可完全符号我们的Wicket组件.用户只要填写form表单,单击save button就可以创建或更新他的联系人;如果想取消的话,单击cancel按钮,就可以放弃所做的修改,回到联系人列表.

?

这样完整的实例为我们揭示了Apache的Wicket框架.虽然我们谈的比较基础,但所有的一切完全可以应用到你的Wicket web应用程序中去.

?

总结

?

文章已经向你介绍了Wicket的核心概念,并且通过一个完整的实例帮助你巩固它们.致使Wicket成功的核心概念其实就是组件和模型.

?

组件就是独立的Java代码块和与它配对的markup文件.大多数组件被设计成抽象类,你可以扩展相应的子类,来满足你的领域特定逻辑和需求,如上面用到的Page, Panel, Link, Form和ListView都是如此.

?

?

模型作为领域对象与Wicket组件之间的桥梁.模型可以有很多特性,可以最大化功能化.理想情况下,你的组件应该永远通过模型来访问你的领域对象.

?

我希望你们会喜欢这篇文章,并且它使得你愿意研究Wicket的更多细节,我觉得我已经找到了一个非常具备高效生产力的框架.

?

?

??????????????????????????????????????????????????????????????????????????????????????????????????????? 全文完

1 楼 lovefly_zero 2008-04-11   其实我也很喜欢Wicket,缺乏可视化的控件是它很大的缺点 2 楼 dellsoft 2008-04-29   有谁有 wicket in action 给共享下

热点排行