Использовать ClickHandler с собственным объектом Javascript?


В Javascript я создаю фигуру SVG и добавляю обработчик кликов к ней следующим образом:

  var rect = document.createElementNS('http://www.w3.org/2000/svg','rect');
  rect.addEventListener('click', myClickHandler, false);

Это прекрасно работает. Я пытаюсь сделать наложение класса Rect в GWT. Если возможно, я хотел бы просто сделать что-то вроде этого:

public class SVGRect extends JavaScriptObject {

    public native void addClickHandler(ClickHandler handler) /*-{
        addEventListener('click', handler, false);
    }-*/;
}

Таким образом, я могу передать "нормальный" обработчик GWT в этот класс и использовать его извне, как любой другой нормальный элемент пользовательского интерфейса GWT. Я не знаю, как подключить объект ClickHandler к собственной реализации javascript объекта правда?

Спасибо

1 4

1 ответ:

Потому что вам нужно ClickEvent, чтобы перейти к ClickHandler.onClick и получение его из JavaScript ставит проблему (AFAICT) - я бы пошел с немного другим, более "общим" подходом:

Создайте простой интерфейс обратного вызова:

public interface Callback {
    void execute();
}

Затем вы можете передать его напрямую и назвать его так:

public native void addClickHandler(Callback callback) /*-{
        addEventListener('click', function() {
           callback.@path.to.your.package.Callback::execute()();
        }, false);
}-*/;

Или создайте промежуточный шаг:

public void addClickHandler(Callback callback) {
    _addClickHandler(getCallback(callback));
}

private native void _addClickHandler(JavaScriptObject callback) /*-{
     addEventListener('click', callback, false);
}-*/;

// This can be moved to a better place
private native static JavaScriptObject getCallback(Callback callback) /*-{
    return function()
    {
        callback.@path.to.your.package.Callback::execute()();
    };
}-*/;

И, конечно, вы бы использовали его так:

SVGRect svg = getMeSVGRect();
svg.addClickHandler(new Callback() {
    @Override
    public void execute() {
        // Do some stuff
    }
});

Лично я предпочитаю второе решение - в то время как это больше кода, я хотел бы сохранить свой методы native / JSNI частные (если это не объект наложения или что-то подобное), а код более читабелен и менее подвержен ошибкам (нет необходимости использовать фанковый синтаксис для вызова функций Java из собственного кода/JSNI).