具有简单子编辑器和空字段的GWT编辑器框架 更新2:更新示例以演示原始问题。如果Person.address最初为null,则绑定失败。
我试图获得一个非常简单的GWT编辑器框架示例,该示例使用子编辑器。我在这里遵循了伪示例 调用driver.flush()时,如果原始Person.address为null,则Person.address的值始终为null-无论我是否在地址的city字段中键入值 下面是我非常简单的POJO类具有简单子编辑器和空字段的GWT编辑器框架 更新2:更新示例以演示原始问题。如果Person.address最初为null,则绑定失败。,gwt,editor,Gwt,Editor,我试图获得一个非常简单的GWT编辑器框架示例,该示例使用子编辑器。我在这里遵循了伪示例 调用driver.flush()时,如果原始Person.address为null,则Person.address的值始终为null-无论我是否在地址的city字段中键入值 下面是我非常简单的POJO类 public class Person { private Address address; private String name; ... getters and setters
public class Person {
private Address address;
private String name;
... getters and setters
}
public class Address {
private String city;
... getters and setters
}
现在是编辑
public class PersonEditor extends DialogBox implements Editor<Person> {
TextBox nameEditor = new TextBox();
AddressEditor addressEditor = new AddressEditor();
Button saveButton = new Button("Save");
public PersonEditor() {
VerticalPanel vp = new VerticalPanel();
vp.add(nameEditor);
vp.add(addressEditor);
vp.add(saveButton);
add(vp);
}
public HandlerRegistration addSaveClickHandler(ClickHandler handler) {
return saveButton.addClickHandler(handler);
}
}
公共类PersonEditor扩展对话框编辑器{
TextBox name编辑器=新建TextBox();
AddressEditor AddressEditor=新的AddressEditor();
按钮保存按钮=新按钮(“保存”);
公共人员编辑(){
VerticalPanel vp=新的VerticalPanel();
副总裁(姓名编辑);
副总裁(地址编辑);
vp.add(保存按钮);
添加(vp);
}
公共句柄注册addSaveClickHandler(ClickHandler处理程序){
返回saveButton.addClickHandler(handler);
}
}
地址编辑器再简单不过了。它只是一个文本框
public class AddressEditor extends Composite implements Editor<Address> {
TextBox cityEditor = new TextBox();
public AddressEditor() {
initWidget(cityEditor);
}
}
公共类AddressEditor扩展复合实现编辑器{
TextBox cityEditor=new TextBox();
公共地址编辑器(){
initWidget(cityEditor);
}
}
以及测试程序。如果取消对p.setAddress的注释,它将正常工作
// Empty interface declaration, similar to UiBinder
interface Driver extends SimpleBeanEditorDriver<Person, PersonEditor> {
}
// Create the Driver
Driver driver = GWT.create(Driver.class);
@Override
public void onModuleLoad() {
Person p = new Person();
p.setName("Bob");
Address a = new Address();
a.setCity("Los Angeles");
//p.setAddress(a);
PersonEditor editor = new PersonEditor();
editor.addSaveClickHandler(new ClickHandler() {
@Override
public void onClick(ClickEvent event) {
Person edited = driver.flush();
if (driver.hasErrors()) {
GWT.log("Has errors");
return;
}
GWT.log("Edited Name: " + edited.getName());
GWT.log("Edited City: " + edited.getAddress().getCity());
}
});
driver.initialize(editor);
driver.edit(p);
editor.center(); // show the dialog
}
//空接口声明,类似于UiBinder
接口驱动程序扩展了SimpleBaneditorDriver{
}
//创建驱动程序
Driver-Driver=GWT.create(Driver.class);
@凌驾
moduleload()上的公共void{
人员p=新人员();
p、 设置名称(“Bob”);
地址a=新地址();
a、 setCity(“洛杉矶”);
//p、 设定地址(a);
PersonEditor editor=新建PersonEditor();
addSaveClickHandler(新的ClickHandler(){
@凌驾
公共作废一次点击(点击事件){
编辑人员=driver.flush();
if(driver.hasErrors()){
GWT.log(“有错误”);
回来
}
log(“编辑的名称:”+Edited.getName());
log(“编辑过的城市:+Edited.getAddress().getCity());
}
});
初始化驱动程序(编辑器);
驱动程序编辑(p);
editor.center();//显示对话框
}
当我点击Save时,无论我是否输入城市,都会抛出一个NPE。如果原始person对象具有一些非空地址,则绑定将“双向”正常工作。如果您是正确的,它不会自动创建缺少的实例。在某些情况下,这可能是一项功能,尤其是在使用
OptionalFieldEditor
时
一种想法是让模型的构造函数自动创建这些字段,或者当您在客户机上创建新字段时,继续并下降,同时创建新实例
如果这是一个普遍的需要,并且你觉得你的手有点脏,那么你可以从一些想法开始工作-编辑器驱动程序将生成代理的层次结构,可以使用
EditorDriver.accept(EditorVisitor)
访问这些代理。这将允许您查看当前模型是什么,以及它是否应该在继续之前初始化EditorContext
在这里提供了一些有用的方法,例如setInModel
和getEditedType
,问题是当您发现缺少这些项时如何构造它们,以及何时将它们保留为空(例如,日期、字符串和装箱原语,但您还有其他希望它们为空的用例)。我将为此制作一个生成器
,它的功能有点像RPC反序列化器,跟踪可能需要的构造函数,并将它们映射到类
实例。如果您是正确的,它不会自动创建缺少的实例。在某些情况下,这可能是一项功能,尤其是在使用OptionalFieldEditor
时
一种想法是让模型的构造函数自动创建这些字段,或者当您在客户机上创建新字段时,继续并下降,同时创建新实例
如果这是一个普遍的需要,并且你觉得你的手有点脏,那么你可以从一些想法开始工作-编辑器驱动程序将生成代理的层次结构,可以使用
EditorDriver.accept(EditorVisitor)
访问这些代理。这将允许您查看当前模型是什么,以及它是否应该在继续之前初始化EditorContext
在这里提供了一些有用的方法,例如setInModel
和getEditedType
,问题是当您发现缺少这些项时如何构造它们,以及何时将它们保留为空(例如,日期、字符串和装箱原语,但您还有其他希望它们为空的用例)。我会为此制作一个生成器
,它的功能有点像RPC反序列化器,跟踪可能需要的构造函数,并将它们映射到类
实例。我知道这是一个稍微旧的生成器,但我也面临这个问题,最近开始使用编辑器框架
我发现实现所需功能的最简单方法是让您的地址“编辑器”实现LeafValueEditor。这要求您提供getValue()和setValue()的实现,当分别调用flush()和edit()时,驱动程序将调用它们。无论支持对象是否为null,都会发生这种情况
我在下面提供了一个例子。我测试了这个,它工作得很好。希望对你也一样
public class AddressField extends Composite implements LeafValueEditor<AddressDTO> {
interface Binder extends UiBinder<Widget, AddressField> {}
private static Binder uiBinder = GWT.create(Binder.class);
@UiConstructor
public AddressField() {
initWidget(uiBinder.createAndBindUi(this));
}
@UiField TextBox line1;
@UiField TextBox line2;
@UiField TextBox town;
@UiField TextBox postcode;
@UiField TextBox county;
@UiField TextBox country;
@Override
public void setValue(AddressDTO value) {
line1.setValue(value == null ? null : value.getLine1());
line2.setValue(value == null ? null : value.getLine2());
town.setValue(value == null ? null : value.getTown());
postcode.setValue(value == null ? null : value.getPostcode());
county.setValue(value == null ? null : value.getCounty());
country.setValue(value == null ? null : value.getCountry());
}
@Override
public AddressDTO getValue() {
return new AddressDTO(line1.getValue(), line2.getValue(), postcode.getValue(), town.getValue(), county.getValue(), country.getValue());
}
}
public类AddressField扩展复合值编辑器{
接口绑定器扩展UiBinder{}
私有静态绑定器uiBinder=GWT.create(Binder.class);
@UIC构造函数
公共地址字段(){
initWidget(uiBinder.createAndBindUi(this));
}
@用户界面