Javascript中的GWT自定义事件触发器

时间:2013-08-07 23:06:12

标签: java javascript events gwt backbone.js

我的应用程序是一半GWT和一半Backbone.js。我们正在将应用程序从GWT过渡到Backbone,因此当我们添加新组件时,它们就在Backbone中。我们也用Backbone替换了一些现有的组件。

我正在尝试替换的组件仍然需要能够在某些事件发生时让其GWT容器知道,以便容器可以影响其他GWT组件。我在GWT中有一个本机函数,它引用一个在Javascript中定义函数的全局命名空间。该函数呈现Backbone组件,因此GWT没有对组件本身的引用。

我尝试在GWT中定义一个自定义DOM事件,然后从Backbone代码触发该事件,但要么我做错了,要么就是不这样做。

我在创建自定义事件时引用了这些问题:How to add CSS AnimationEnd event handler to GWT widget?& GWT Custom Events

我尝试了两次尝试从Backbone触发自定义事件并让GWT听取它,但都没有工作。

我需要帮助从Javascript(Backbone.js)触发一个事件(或调用一个回调或类似的东西),这些事件将在GWT中被“听到”(或被叫或其他)。

代码

两次尝试之间共同的代码是如何呈现Backbone组件以及如何触发事件:

来自班级BackboneController.java

public static void loadMessageEntry(final String selector, final String type, final QuipuId conversationID, final QuipuId messageID, final boolean enterIsSubmit) {
    String messageIDString = messageID.getId();
     String enterRole = enterIsSubmit ? "submit" : "newline";
     if(messageID.equals(QuipuId.NULL)) {
         messageIDString = "";
     }
     showMessageEntry(selector, type, conversationID.getId(), messageIDString, enterRole);
}
private static native void showMessageEntry(String selector, String type, String messageId, String conversationId, String enterRole) /*-{
    var intervalTimer = $wnd.setInterval(function() {
        if($wnd.Namespace.MessageEntry) {
            $wnd.Namespace.MessageEntry.displayMessageEntry(selector, type, messageId, conversationId, enterRole);
            $wnd.clearInterval(intervalTimer);
        }
    }, 500);
}-*/;

来自班级myClientBootstrap.js

Namespace.MessageEntry = Namespace.MessageEntry || {};
Namespace.MessageEntry.displayMessageEntry = function(selector, type, conversationID, messageID, enterRole) {
  var messageEntry, 
      instanceName = selector.slice(1);
  if(CKEDITOR.instances[instanceName]) {
    CKEDITOR.instances[instanceName].trigger("show");
  } else {
    messageEntry = new MessageEntry( { 
      model: new RTEModel({mode: 'inline', type: type, conversationID: conversationID, messageID: messageID}),
      enterRole: enterRole
    });
    $(selector).append(messageEntry.$el);
  }
};

来自班级MessageEntryView.js

// called when the upload button is clicked
openDocumentUploader: function() {
  $("." + this.model.get("id")).trigger('messageEntry',["documentUpload"]);
}

来自班级MessageEntry.java

尝试1

private native void registerMessageEntryEventHandler(final Element messageEntry, final MessageEntryHandler handler) /*-{
    var callback = function() {
        handler.@mypath.client.MessageEntryHandler::onMessageEntryEvent(Lmypath/client/MessageEntryEvent;)();
    }
    messageEntry.addEventListener("messageEntry", callback, false);     
}-*/;

private void initLayout() {
    initWidget(mainDockLayoutPanel);

    Conversation model = conversationController.getModel();
    messageEntryPanel.getElement().addClassName("richTextAreaId" + model.getId());
    BackboneController.loadMessageEntry(".richTextAreaId" + model.getId(), "message", model.getId(), QuipuId.NULL, (Boolean)PreferencesModel.getInstance().isAutoSubmit());

    registerMessageEntryEventHandler(messageEntryPanel.getElement(), new MessageEntryHandler() {
        @Override
        public void onMessageEntryEvent(MessageEntryEvent event) {
            if(event.getEventType() == "documentUpload") {
                MessageEntry.this.switchToDocumentUpload();
            }
        }
    });
    mainDockLayoutPanel.addStyleName(MessageEntryBundle.instance.css().container());

    modeSimplePanel.add(messageEntryPanel);
    mainDockLayoutPanel.add(modeSimplePanel);
}

尝试2

private void initLayout() {
    initWidget(mainDockLayoutPanel);

    Conversation model = conversationController.getModel();
    messageEntryPanel.getElement().addClassName("richTextAreaId" + model.getId());
    BackboneController.loadMessageEntry(".richTextAreaId" + model.getId(), "message", model.getId(), QuipuId.NULL, (Boolean)PreferencesModel.getInstance().isAutoSubmit());
    addDomHandler(new MessageEntryHandler() {
        @Override
        public void onMessageEntryEvent(MessageEntryEvent event) {
            if(event.getEventType() == "documentUpload") {
                MessageEntry.this.switchToDocumentUpload();
            }
        }
    }, MessageEntryEvent.getType());
    mainDockLayoutPanel.addStyleName(MessageEntryBundle.instance.css().container());

    modeSimplePanel.add(messageEntryPanel);
    mainDockLayoutPanel.add(modeSimplePanel);
}

修改

再做一次尝试,这比前两次有更多的区别。当我们创建命名空间时,我们执行_.extend(Namespace, Backbone.Events),以便我们可以触发Backbone代码将侦听的GWT事件。我决定尝试让它在另一个方向上工作。它没有。

尝试3

来自MessageEntryView.js

openDocumentUploader: function() {
  Namespace.trigger(Namespace.Events.UPLOAD);
}

来自MessageEntry.java

private native void registerUploadListener(MessageEntry msgEntry) /*-{
    $wnd.Namespace.on($wnd.Namespace.Events.UPLOAD, function() {
        msgEntry.@mypath.widget.MessageEntry::switchToDocumentUpload();
    });
}-*/;

private void initLayout() {
    initWidget(mainDockLayoutPanel);

    Conversation model = conversationController.getModel();
    messageEntryPanel.getElement().addClassName("richTextAreaId" + model.getId());
    BackboneController.loadMessageEntry(".richTextAreaId" + model.getId(), "message", model.getId(), QuipuId.NULL, (Boolean)PreferencesModel.getInstance().isAutoSubmit());
    registerUploadListener(this);
    mainDockLayoutPanel.addStyleName(MessageEntryBundle.instance.css().container());

    modeSimplePanel.add(messageEntryPanel);
    mainDockLayoutPanel.add(modeSimplePanel);
}

1 个答案:

答案 0 :(得分:7)

尝试3是做了什么。我刚从本机方法错误地调用了GWT方法。

使用Global命名空间并将其扩展为使用Backbone事件,我只需要Backbone视图触发Global事件,并且GWT视图侦听事件。

尝试3

来自MessageEntryView.js

openDocumentUploader: function() {
  Namespace.trigger(Namespace.Events.UPLOAD);
}

来自MessageEntry.java

private native void registerUploadListener(MessageEntry instance) /*-{
    $wnd.Namespace.on($wnd.Namespace.Events.UPLOAD, function() {
        instance.@mypath.widget.MessageEntry::switchToDocumentUpload()();
    });
}-*/;

private void initLayout() {
    initWidget(mainDockLayoutPanel);

    Conversation model = conversationController.getModel();
    messageEntryPanel.getElement().addClassName("richTextAreaId" + model.getId());
    BackboneController.loadMessageEntry(".richTextAreaId" + model.getId(), "message", model.getId(), QuipuId.NULL, (Boolean)PreferencesModel.getInstance().isAutoSubmit());
    registerUploadListener(this);
    mainDockLayoutPanel.addStyleName(MessageEntryBundle.instance.css().container());

    modeSimplePanel.add(messageEntryPanel);
    mainDockLayoutPanel.add(modeSimplePanel);
}