我编写了一个包含JQUeryUI对话框的简单类。它基本上是这样的:
public class Dialog extends Composite
{
final String id;
public Dialog(IsWidget body) {
initWidget(body.asWidget());
id = DOM.createUniqueId();
getElement().setId(id);
}
public void create() {
create(id);
}
public void open() {
open(id);
}
final native void create(String id) /*-{
$wnd.jQuery("#" + id).dialog({ autoHide: true });
}-*/;
final native void open(String id) /*-{
$wnd.jQuery("#" + id).dialog("open");
}-*/;
}
我传递了初始化视图(我正在使用uibinder模板)。当视图仅包含简单的HTML元素(如复选框)时,它可以正常工作,但当它包含复杂的小部件(如公开面板或单元格列表)时,面板无法响应单击事件。披露面板没有打开,单元格列表也没有响应事件,尽管这两个视图在它们被安置在“GWT弹出面板”之前工作正常。
这是更多源代码,显示了如何初始化Dialog。
HasDialog parent = (HasDialog) body;
Dialog dialog = parent.getDialog();
dialog.open();
FYI HasDialog只是小部件继承的接口。
interface HasDialog { Dialog getDialog(); }
例如,包含公开面板小部件的小部件如下所示:
final Dialog dialog;
@Override
public Dialog getDialog()
{
if (dialog == null) { // only one instance
dialog = new Dialog(this);
dialog.create();
}
// dialog buttons and events have been commented out
return dialog;
}
我们可以假设小部件没有内部问题,因为它与GWT弹出式面板一起使用时工作正常:
PopupPanel popup = new PopupPanel();
popup.setWidget(body);
popup.center();
我同意logan,我认为 onAttach 或 onLoad 事件正在陷入视图子窗口小部件。我注意到这些方法受到保护。什么是正确的接线这些正确的?
我已经缩小了小部件(通过构造函数传递)没有附加到DOM的问题 - 就小部件本身而言。
public void open()
{
open(id);
if (getWidget().isAttached() == false) {
Window.alert("Widget not attached");
}
}
我相信Widget Javadoc为我的情况提供了一些相关信息。
protected void doAttachChildren()
如果窗口小部件包含一个或多个不在其中的子窗口小部件 逻辑窗口小部件层次结构(子项仅在物理上连接 在DOM级别),它必须覆盖此方法并调用onAttach() 每个子小部件。
鉴于Dialog类应该可以处理任何窗口小部件,我不想下载我的窗口小部件并开始编写大量样板文件,当然必须有一种优雅地附加窗口小部件的方法。想法?
答案 0 :(得分:1)
修改您的打开方法:
public void open() {
onAttach();
RootPanel.detachOnWindowClose(this);
open(id);
}
添加关闭处理程序:
void onClose() {
if(RootPanel.isInDetachList(this)) {
RootPanel.detachNow(this);
}
else {
onDetach();
}
}
在创建对话框时注册onclose处理程序:
final native void create(String id) /*-{
var _self = this;
$wnd.jQuery("#" + id).dialog({
autoHide: true,
close: function(event, ui) {
_self.@your.package.Dialog::onClose()();
_self = null;
}
});
}-*/;
让其余的保持不变;)
编辑: 事实上,您甚至不必生成DomNode的id,因为您可以直接在DomNode上实例化Jquery对象。修改后的全班:
public class Dialog extends Composite {
public Dialog(IsWidget body) {
initWidget(body.asWidget());
}
public void create() {
create(getElement());
}
public void open() {
onAttach();
RootPanel.detachOnWindowClose(this);
open(getElement());
}
void onClose() {
if(RootPanel.isInDetachList(this)) {
RootPanel.detachNow(this);
}
else {
onDetach();
}
}
final native void create(Element element) /*-{
var _self = this;
$wnd.jQuery(element).dialog({
autoHide: true,
close: function(event, ui) {
_self.@your.package.Dialog::onClose()();
_self = null;
}
});
}-*/;
final native void open(Element element) /*-{
$wnd.jQuery(element).dialog("open");
}-*/;
}