我正在尝试使用一个非常简单的GWT编辑器框架示例与子编辑器一起工作。我在这里跟随伪示例http://code.google.com/webtoolkit/doc/latest/DevGuideUiEditors.html
当我调用driver.flush()时,如果原始Person.address为null,则Person.address的值始终为null - 无论我是否在地址的city字段中键入值。
这是我非常简单的POJO课程。
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);
}
}
地址编辑器不可能更简单。它只是一个TextBox
public class AddressEditor extends Composite implements Editor<Address> {
TextBox cityEditor = new TextBox();
public AddressEditor() {
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
}
当我点击保存时,无论我是否输入城市,都会抛出NPE。如果原始person对象具有一些非空地址,则绑定将以“两种”方式正常工作。
答案 0 :(得分:0)
你是对的,它不会自动创建缺少的实例。在某些情况下,这可能是一项功能,尤其是在使用OptionalFieldEditor
时。
一种想法是让你的模型的构造函数自动创建这些字段,或者当你在客户端上创建它们时,继续前进和下降,随时创建新实例。
如果这是一般性的需求,并且你觉得让自己的手变得有点脏,那么你可以使用一些想法 - 编辑器驱动程序将生成一个代理层次结构,可以使用{{1}访问}。这将允许您查看当前模型是什么,以及是否应该在继续之前初始化。 EditorDriver.accept(EditorVisitor)
在这里提供了一些有用的方法,例如EditorContext
和setInModel
,问题将是如何构建这些项目,因为您发现它们丢失,以及何时将它们留空(Date,例如,字符串和盒装基元,但您有其他用例,您希望它们为空白)。我会为此创建一个getEditedType
,其功能有点像RPC反序列化器,跟踪可能需要的构造函数,并将它们映射到Generator
实例。
答案 1 :(得分:0)
感谢这是一个稍微陈旧的,但我也面临这个问题,最近开始玩编辑框架。
我发现实现所需功能的最简单方法是让你的地址“编辑器”实现LeafValueEditor。这要求您提供getValue()和setValue()的实现,当分别调用flush()和edit()时,驱动程序将调用它们。无论后备对象是否为空,都会发生这种情况。
我在下面提供了一个例子。我测试了它,它完美地工作。希望它也适合你!
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());
}
}