Если Вы действительно ищете окончательный соответствие, Вы, вероятно, находите его на" А Хорошее Регулярное выражение URL? ".
, Но regex, который действительно соответствует всем возможным доменам и позволяет что-либо, что позволяется согласно RFCs, ужасно длинно и нечитабелен, доверяйте мне;-)
Хильбранд прав в том, что проблема заключается в том, что метод GWT onAttach ()
не был вызван.
Я реализовал ваше исходное решение, добавив следующий метод в ] ElementWrapper
:
public void onAttach() {
super.onAttach();
}
И вызывается добавленным wrapper.onAttach ()
после создания ElementWrapper
. Работает как шарм!
Вы можете использовать JSNI для повторного использования вашего фрагмента кода JavaScript. Ваш код javascript вызовет метод gwt для объекта, который бросит его от имени кнопки в iframe.
Что касается того, почему код GWT не работает - я думаю, это потому, что они используют некоторый слой поверх обычного события браузера, которые, вероятно, не могут охватывать более 1 кадра. Это всего лишь предположение. Вы можете отправить это как запрос функции / ошибки команде GWT. Если я прав, ваш код выглядит нормально.
Изучив это дальше, я обнаружил, что 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
Я полагаю, проблема в том, что метод 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);
См. Мой предыдущий ответ. Небольшое изменение исходного решения заставит его работать.
Вы можете найти это полезным:
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 делает это таким трудным и плохо документированным.