Как выставить события от дочерних объектов на содержащем составном объекте? - PullRequest
2 голосов
/ 20 августа 2011

У меня есть составной виджет, который содержит много кнопок (например, Button1, Button2 и т. Д.).Я не могу понять, как выставить события нажатия кнопки на составном виджете.Я пытаюсь избежать создания пользовательских событий, таких как Button1ClickEvent и Button2ClickEvent, и вместо этого повторно использую существующее GWT ClickEvent для них обоих.Следующий фрагмент кода может дать представление о том, что я пытаюсь сделать:

public class WidgetWithTwoButtons extends Composite {
    ...

    @UiField Button button1;
    @UiField Button button2;

    @UiHandler("button1")
    void onButton1Click(ClickEvent event) {
            // TODO fire click event on Button1ClickHandler
    }

    public HandlerRegistration addButton1ClickHandler(ClickHandler handler) {
            return addDomHandler(handler, ClickEvent.getType());
    }

    @UiHandler("button2")
    void onButton1Click(ClickEvent event) {
            // TODO fire click event on Button2ClickHandler
    }

    public HandlerRegistration addButton2ClickHandler(ClickHandler handler) {
            return addDomHandler(handler, ClickEvent.getType());
    }
}

Я думаю, что это не лучшая практика.Буду признателен, если вы дадите ссылки на рекомендуемые решения / примеры этой проблемы в своих ответах.Спасибо!

1 Ответ

3 голосов
/ 20 августа 2011

Я начал думать о вашей проблеме и впервые заметил, что вместо использования addDomHandler вы можете изменить текущий addButton1ClickHandler(ClickHandler handler) просто на:

public HandlerRegistration addButton1ClickHandler(ClickHandler handler) {
    return button1.addClickHandler(handler);
}

Если у вас была только одна кнопка, вы можете открыть ее,заставить ваш Composite реализовать HasClickHandlers и реализовать метод, описанный ниже, чтобы передать его вашей кнопке:

@Override
public HandlerRegistration addClickHandler(ClickHandler handler) {
    return button1.addClickHandler(handler);
}

Но поскольку у вас много кнопок, вам нужен метод, который берет нужную кнопкучтобы добавить свой clickHandler в качестве параметра, такого как:

public HandlerRegistration addClickHandlerToButton(ClickHandler handler, Button target){
    return target.addClickHandler(handler);
}

Проблема этого подхода заключается в том, что для его использования вам необходимо иметь ссылку на ваши кнопки, что означает, что вам нужно определить методы получения для ваших кнопокв вашем композите, например public Button getButton1().Когда вы выставляете свои кнопки таким образом, проблема заключается в том, что вам больше не нужен метод сквозного ввода в композите, так как он / она может в любом случае напрямую обращаться к кнопкам, что делает приведенный выше подход, который использует целевую кнопку в качестве параметра устаревшего.Хуже всего то, что он / она может даже изменить стили и даже отсоединить эти кнопки.

Чтобы решить эту проблему, вы можете выставить свои кнопки через интерфейс HasClickHandlers.

Так что, ИМХО, я так и считаюдолжно быть сделано:

public class ComplexComposite extends Composite {

    private Button button1 = new Button("btn1");
    private Button button2 = new Button("btn2");

    public ComplexComposite(){
        HorizontalPanel panel = new HorizontalPanel();
        panel.add(button1);
        panel.add(button2);
        initWidget(panel);
    }   
    public HasClickHandlers getButton1(){
        return button1;
    }
    public HasClickHandlers getButton2(){
        return button2;
    }   
}

При таком подходе вы выставляете свои кнопки только над желаемым интерфейсом, и можно добавить обработчики кликов, такие как:

ComplexComposite composite = new ComplexComposite();
composite.getButton1().addClickHandler(new ClickHandler() {
    @Override
    public void onClick(ClickEvent event) {
        ...
    }
});
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...