GWT SelectBox ChangeHandler 事件不起作用
GWT SelectBox ChangeHandler event doesn't work
样本:
private Widget getSelectBox() {
HorizontalPanel hPanel = new HorizontalPanel();
hPanel.setSpacing(20);
final ListBox dropBox = new ListBox(false);
String[] listTypes = {"1", "2", "3"};
for (int i = 0; i < listTypes.length; i++) {
dropBox.addItem(listTypes[i]);
}
dropBox.ensureDebugId("cwListBox-dropBox");
dropBox.getElement().setId("cms-dropBox");
VerticalPanel dropBoxPanel = new VerticalPanel();
dropBoxPanel.setSpacing(4);
dropBoxPanel.add(dropBox);
hPanel.add(dropBoxPanel);
dropBox.addChangeHandler(new ChangeHandler() {
public void onChange(ChangeEvent event) {
Window.alert("change fired");
dropBox.addItem("else");
consoleLog("selected: "+ dropBox.getSelectedIndex());
}
});
return hPanel;
}
ChangeHandler 不工作。虽然在官方例子中它工作正常
(http://samples.gwtproject.org/samples/Showcase/Showcase.html#!CwListBox
).但它不适用于此代码。没有错误。
DOM.sinkEvents((com.google.gwt.user.client.Element) dropBox.getElement(), Event.ONCHANGE );
DOM.setEventListener((com.google.gwt.user.client.Element) dropBox.getElement(), new EventListener() {
@Override
public void onBrowserEvent(Event event) {
if (DOM.eventGetType(event) == Event.ONCHANGE) {
Window.alert("change fired");
dropBox.addItem("who");
consoleLog("selected: "+ dropBox.getSelectedIndex());
}
}
});
这种方式也不行。
upd:所有在 MainEntryPoint class 中都有效,但需要 panel.add(new SomeClass().getWidget()),但这是行不通的
因此,您只需要从另一个 class 连接一个 ListBox ChangeEvent
。您可以通过多种方式做到这一点。这里有两个简单的方法。
我们假设在 class A
中定义了一个 ListBox,而您需要在 class B
中定义一个处理程序。
- 第一种方法:从
class A
公开一个 ListBox 并在 class B
中使用它来设置处理程序。
- 第二种方法:在
class A
中添加一个public方法,在ListBox上设置一个处理程序,这将在class B
中使用。
您需要将 class A
的实例传递给 class B
的构造函数。
public class A {
private ListBox dropBox;
public A() {
// constructor - set up dropBox
...
}
// first method - expose a dropBox
public ListBox getDropBox() {
return dropBox;
}
// second method - allow external handlers
public HandlerRegistration addListBoxChangeHandler(ChangeHandler handler) {
return dropBox.addChangeHandler(handler);
}
}
public class B {
private A instanceOfClassA;
public B(A instanceOfClassA) {
// constructor
this.instanceOfClassA = instanceOfClassA;
...
// first method - dropBox is exposed in class A
instanceOfClassA.getDropBox().addChangeHandler(handler);
// second method - add external handler
instanceOfClassA.addListBoxChangeHandler(handler);
}
}
第二种方法比较优雅
eventListener不工作的原因:注意力不集中。
在添加带有 eventListener
的任何小部件后,不要覆盖 DOM 的 DOM 内容,例如 container.getElement().setInnerHTML(container.getElement().getInnerHTML()+"<div>somehtml</div>");
样本:
private Widget getSelectBox() {
HorizontalPanel hPanel = new HorizontalPanel();
hPanel.setSpacing(20);
final ListBox dropBox = new ListBox(false);
String[] listTypes = {"1", "2", "3"};
for (int i = 0; i < listTypes.length; i++) {
dropBox.addItem(listTypes[i]);
}
dropBox.ensureDebugId("cwListBox-dropBox");
dropBox.getElement().setId("cms-dropBox");
VerticalPanel dropBoxPanel = new VerticalPanel();
dropBoxPanel.setSpacing(4);
dropBoxPanel.add(dropBox);
hPanel.add(dropBoxPanel);
dropBox.addChangeHandler(new ChangeHandler() {
public void onChange(ChangeEvent event) {
Window.alert("change fired");
dropBox.addItem("else");
consoleLog("selected: "+ dropBox.getSelectedIndex());
}
});
return hPanel;
}
ChangeHandler 不工作。虽然在官方例子中它工作正常 (http://samples.gwtproject.org/samples/Showcase/Showcase.html#!CwListBox ).但它不适用于此代码。没有错误。
DOM.sinkEvents((com.google.gwt.user.client.Element) dropBox.getElement(), Event.ONCHANGE );
DOM.setEventListener((com.google.gwt.user.client.Element) dropBox.getElement(), new EventListener() {
@Override
public void onBrowserEvent(Event event) {
if (DOM.eventGetType(event) == Event.ONCHANGE) {
Window.alert("change fired");
dropBox.addItem("who");
consoleLog("selected: "+ dropBox.getSelectedIndex());
}
}
});
这种方式也不行。
upd:所有在 MainEntryPoint class 中都有效,但需要 panel.add(new SomeClass().getWidget()),但这是行不通的
因此,您只需要从另一个 class 连接一个 ListBox ChangeEvent
。您可以通过多种方式做到这一点。这里有两个简单的方法。
我们假设在 class A
中定义了一个 ListBox,而您需要在 class B
中定义一个处理程序。
- 第一种方法:从
class A
公开一个 ListBox 并在class B
中使用它来设置处理程序。 - 第二种方法:在
class A
中添加一个public方法,在ListBox上设置一个处理程序,这将在class B
中使用。
您需要将 class A
的实例传递给 class B
的构造函数。
public class A {
private ListBox dropBox;
public A() {
// constructor - set up dropBox
...
}
// first method - expose a dropBox
public ListBox getDropBox() {
return dropBox;
}
// second method - allow external handlers
public HandlerRegistration addListBoxChangeHandler(ChangeHandler handler) {
return dropBox.addChangeHandler(handler);
}
}
public class B {
private A instanceOfClassA;
public B(A instanceOfClassA) {
// constructor
this.instanceOfClassA = instanceOfClassA;
...
// first method - dropBox is exposed in class A
instanceOfClassA.getDropBox().addChangeHandler(handler);
// second method - add external handler
instanceOfClassA.addListBoxChangeHandler(handler);
}
}
第二种方法比较优雅
eventListener不工作的原因:注意力不集中。
在添加带有 eventListener
的任何小部件后,不要覆盖 DOM 的 DOM 内容,例如container.getElement().setInnerHTML(container.getElement().getInnerHTML()+"<div>somehtml</div>");