GWT Editor Framework с простым подредактором и пустыми полями - PullRequest
2 голосов
/ 15 марта 2012

UPDATE2: обновлен пример для демонстрации исходной проблемы.Если Person.address изначально имеет значение null, привязка завершается неудачей.

Я пытаюсь получить очень простой пример структуры редактора GWT, работающий с субредакторами.Я следовал псевдо-примеру здесь http://code.google.com/webtoolkit/doc/latest/DevGuideUiEditors.html

Когда я вызываю driver.flush (), значение Person.address всегда равно нулю, если исходный Person.address равен нулю - независимо от того, набрал ли язначение в поле города адреса.

Вот мои очень простые классы 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 имеет некоторый ненулевой адрес, привязка будет нормально работать в обоих направлениях.

Ответы [ 2 ]

0 голосов
/ 01 августа 2015

Признаю, что это немного старая проблема, но я тоже столкнулся с этой проблемой, недавно начал играть со структурой редактора.

Я обнаружил, что самый простой способ реализовать требуемую функциональность состоит в том, чтобы ваш адресный «редактор» реализовал 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());
    }
}
0 голосов
/ 16 марта 2012

Вы правы, он не будет автоматически создавать пропущенные экземпляры.В некоторых случаях это может быть функцией, особенно при использовании OptionalFieldEditor.

Одна мысль состоит в том, чтобы заставить конструктор вашей модели автоматически создавать эти поля или когда вы создаете их новыми на клиенте, продолжайте и спускайтесь, создавая новые экземпляры по ходу работы.

Если это будет общей потребностью, и вам захочется немного испачкать руки, некоторые идеи для вас - драйвер редактора создаст иерархию делегатов, которую можно посетить с помощью EditorDriver.accept(EditorVisitor).Это позволит вам увидеть, что представляет собой текущая модель, и следует ли ее инициализировать перед продолжением.EditorContext предоставляет несколько полезных методов, таких как setInModel и getEditedType, вопрос заключается в том, как создать эти элементы, когда вы обнаружите, что они отсутствуют, и когда оставить их пустыми (Date, String и примитивы в штучной упаковке,например, но у вас есть другие варианты использования, где вы хотите, чтобы они были пустыми).Я бы сделал для этого Generator, который бы работал как десериализатор RPC, отслеживая возможные необходимые конструкторы и сопоставляя их с Class экземплярами.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...