GWT JQueryUI Dialog包装器不是“附加小部件”

时间:2012-10-04 09:15:54

标签: java jquery-ui gwt jsni

我编写了一个包含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 事件正在陷入视图子窗口小部件。我注意到这些方法受到保护。什么是正确的接线这些正确的?

更新2

我已经缩小了小部件(通过构造函数传递)没有附加到DOM的问题 - 就小部件本身而言。

public void open()
{
    open(id);
    if (getWidget().isAttached() == false) {
        Window.alert("Widget not attached");
    }
}

我相信Widget Javadoc为我的情况提供了一些相关信息。

  

protected void doAttachChildren()

     

如果窗口小部件包含一个或多个不在其中的子窗口小部件   逻辑窗口小部件层次结构(子项仅在物理上连接   在DOM级别),它必须覆盖此方法并调用onAttach()   每个子小部件。

鉴于Dialog类应该可以处理任何窗口小部件,我不想下载我的窗口小部件并开始编写大量样板文件,当然必须有一种优雅地附加窗口小部件的方法。想法?

1 个答案:

答案 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");
    }-*/;
}