Сцепление события GWT на элемент во внешнем iframe

Если Вы действительно ищете окончательный соответствие, Вы, вероятно, находите его на" А Хорошее Регулярное выражение URL? ".

, Но regex, который действительно соответствует всем возможным доменам и позволяет что-либо, что позволяется согласно RFCs, ужасно длинно и нечитабелен, доверяйте мне;-)

11
задан triggerNZ 16 July 2009 в 23:17
поделиться

6 ответов

Хильбранд прав в том, что проблема заключается в том, что метод GWT onAttach () не был вызван.

Я реализовал ваше исходное решение, добавив следующий метод в ] ElementWrapper :

  public void onAttach() {
    super.onAttach();
  }

И вызывается добавленным wrapper.onAttach () после создания ElementWrapper . Работает как шарм!

10
ответ дан 3 December 2019 в 07:14
поделиться

Вы можете использовать JSNI для повторного использования вашего фрагмента кода JavaScript. Ваш код javascript вызовет метод gwt для объекта, который бросит его от имени кнопки в iframe.

Что касается того, почему код GWT не работает - я думаю, это потому, что они используют некоторый слой поверх обычного события браузера, которые, вероятно, не могут охватывать более 1 кадра. Это всего лишь предположение. Вы можете отправить это как запрос функции / ошибки команде GWT. Если я прав, ваш код выглядит нормально.

0
ответ дан 3 December 2019 в 07:14
поделиться

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

Я в основном исправил это, используя JSNI для репликации части механизма обработки событий GWT. Следующие работы:

Element buttonElement = DOM.getElementById("externalButton");
new CustomElementWrapper(buttonElement).addClickHandler(new ClickHandler() {
public void onClick(ClickEvent event) {
        Window.alert("GWT hooked into button");
    }
});

Где CustomElementWrapper:

public class CustomElementWrapper extends Widget implements HasClickHandlers {
    private ClickEventManager clickEventManager;

    public CustomElementWrapper(Element theElement) {
        setElement(theElement);
        clickEventManager = new ClickEventManager(theElement);
    }

    public HandlerRegistration addClickHandler(ClickHandler handler) {
        //The 'right' way of doing this would be the code below. However, this doesn't work
        // A bug in GWT?
        //      
        //              return addDomHandler(handler, ClickEvent.getType());
        return clickEventManager.registerClickHandler(handler);
    }


    void invokeClickHandler() {
        clickEventManager.invokeClickHandler();
    }

    public boolean isClickHandlerRegistered() {
        return clickEventManager.isClickHandlerRegistered();
    }
}

И, наконец, ClickEventManager, где происходит реальная работа:

public class ClickEventManager {
private boolean clickHandlerRegistered = false;
private ClickHandler clickHandler;
private Element element;

public ClickEventManager(Element element) {
    this.element = element;
}

public void invokeClickHandler() {
    //This shouldn't really be null but we are bypassing GWT's native event mechanism
    //so we can't create an event
    clickHandler.onClick(null);
}

public boolean isClickHandlerRegistered() {
    return clickHandlerRegistered;
}

HandlerRegistration registerClickHandler(ClickHandler handler) {
    clickHandler = handler;

    if (!clickHandlerRegistered) {
        registerClickHandlerInJS(element);
        clickHandlerRegistered = true;
    }
    return new HandlerRegistration() {
        public void removeHandler() {
            //For now, we don't support the removal of handlers
            throw new UnsupportedOperationException();
        }
    };
}
private native void registerClickHandlerInJS(Element element)/*-{
    element.__clickManager = this;
    element.onclick 
        = function() {
            var cm = this.__clickManager; 
            cm.@com.talktactics.agent2.client.widgets.ClickEventManager::invokeClickHandler()();
        }
}-*/;
}

Лично я ненавижу это решение, потому что я, кажется, дублирую обработку событий GWT и, вполне возможно, представляю неприятный javascript утечки памяти. Мы будем благодарны за любые идеи о том, почему мой первый пост не работает (учитывая, что аспект iframe - отвлекающий маневр).

Спасибо,

Tin

1
ответ дан 3 December 2019 в 07:14
поделиться

Я полагаю, проблема в том, что метод GWT onAttach () не вызывается, когда вы используете упаковку, как в вашем первом примере. Вы можете попробовать использовать статический метод wrap для виджета Button. Хотя, чтобы использовать это, вход должен быть типа кнопки . Или взгляните на реализацию метода wrap . Вот модифицированный код при использовании метода wrap :

Element buttonElement = finder(frameDocument).tag("input").name(buttonElementName).findOne();
Button button = Button.wrap(buttonElement);
HandlerRegistration handlerRegistration = button.addClickHandler(clickHandler);
4
ответ дан 3 December 2019 в 07:14
поделиться

См. Мой предыдущий ответ. Небольшое изменение исходного решения заставит его работать.

0
ответ дан 3 December 2019 в 07:14
поделиться

Вы можете найти это полезным:

import com.google.gwt.dom.client.Element;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.event.dom.client.HasClickHandlers;
import com.google.gwt.event.shared.HandlerRegistration;
import com.google.gwt.user.client.ui.AbsolutePanel;

public class DirectPanel extends AbsolutePanel implements HasClickHandlers {
        public DirectPanel(Element elem) {
                super(elem.<com.google.gwt.user.client.Element> cast());
                onAttach();
        }

        @Override
        public HandlerRegistration addClickHandler(ClickHandler handler) {
                return addDomHandler(handler, ClickEvent.getType());
        }
}

Затем вы сможете превращать произвольные контейнеры в контейнеры виджетов:

  Element root = Document.get().getElementById("target");
  DirectPanel p = new DirectPanel(root);
  Button register = new Button("Register");
  register.addClickHandler(new ClickHandler() {
    @Override
    public void onClick(ClickEvent event) {
      // ...
    }
  });
  p.add(register);

И связывать события с произвольными элементами:

  Element root = Document.get().getElementById("target");
  DirectPanel p = new DirectPanel(root);
  p.addClickHandler(new ClickHandler() {
    @Override
    public void onClick(ClickEvent event) {
      // ...
    }
  });

В частности, в вашем случае попробуйте следующее:

IFrameElement frm = Document.get().createIFrameElement();
Document d = frm.getContentDocument();
NodeList<Element> inputs = d.getElementsByTagName("input");
InputElement target = null;
for(int i = 0; i < inputs.getLength(); ++i) {
  Element e = inputs.getItem(0);
  if (e.getNodeName().equals("submit")) {
    target = InputElement.as(e);
    break;
  }
}
if (target != null) {
  DirectPanel p = new DirectPanel(target);
  p.addClickHandler(new ClickHandler() {
    @Override
    public void onClick(ClickEvent event) {
      // TODO Auto-generated method stub
    }
  });
}

Это всегда озадачивал меня тем, что GWT делает это таким трудным и плохо документированным.

1
ответ дан 3 December 2019 в 07:14
поделиться
Другие вопросы по тегам:

Похожие вопросы: