简体   繁体   English

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

[英]GWT Custom event trigger in Javascript

I have an application that is half GWT and half Backbone.js. 我有一个应用程序是一半GWT和一半Backbone.js。 We're transitioning the app from GWT to Backbone so as we add new components, they're in Backbone. 我们正在将应用程序从GWT过渡到Backbone,因此当我们添加新组件时,它们就在Backbone中。 We're also replacing some existing components with Backbone as well. 我们也用Backbone替换了一些现有的组件。

There's a component that I'm attempting to replace that still needs to be able to let its GWT container know when certain events occur so that the container can impact other GWT components. 我试图替换的组件仍然需要能够让其GWT容器知道何时发生某些事件,以便容器可以影响其他GWT组件。 I have a native function in GWT that references a Global namespace on which a function is defined in Javascript. 我在GWT中有一个本机函数,它引用一个在Javascript中定义函数的全局命名空间。 That function renders the Backbone component, so GWT doesn't have a reference to the component itself. 该函数呈现Backbone组件,因此GWT没有对组件本身的引用。

I tried defining a custom DOM Event in GWT and then triggering that event from the Backbone code, but either I did it wrong, or that's not the way to do it. 我尝试在GWT中定义一个自定义DOM事件,然后从Backbone代码触发该事件,但要么我做错了,要么就是不这样做。

I referenced these questions in creating my custom event: How to add CSS AnimationEnd event handler to GWT widget? 我在创建自定义事件时引用了这些问题: 如何将CSS AnimationEnd事件处理程序添加到GWT窗口小部件? & GWT Custom Events GWT自定义活动

I made two attempts at triggering the custom event from Backbone and having GWT listen for it, neither worked. 我做了两次尝试从Backbone触发自定义事件并让GWT听取它,但都没有工作。

I need help triggering an event (or calling a callback, or something equivalent) from Javascript (Backbone.js) that will be "heard" (or called or whatever) in GWT. 我需要帮助从Javascript(Backbone.js)触发一个事件(或调用一个回调或类似的东西),这些事件将在GWT中被“听到”(或被叫或其他)。

CODE

Code common between two attempts is how the Backbone component is rendered and how the event is triggered: 两次尝试之间共同的代码是如何呈现Backbone组件以及如何触发事件:

From class BackboneController.java : 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);
}-*/;

From class myClientBootstrap.js : 从类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);
  }
};

From class MessageEntryView.js : 从类MessageEntryView.js

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

From class MessageEntry.java : 从类MessageEntry.java

Attempt 1 尝试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);
}

Attempt 2 尝试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);
}

EDIT 编辑

Made another attempt, this has a few more differences than between the first two. 再做一次尝试,这比前两次有更多的区别。 When we create our namespace, we do _.extend(Namespace, Backbone.Events) so that we can trigger events from GWT that the Backbone code will listen for. 当我们创建命名空间时,我们执行_.extend(Namespace, Backbone.Events)以便我们可以触发Backbone代码将侦听的GWT事件。 I decided to try getting it to work in the other direction. 我决定尝试让它在另一个方向上工作。 It didn't. 它没有。

Attempt 3 尝试3

From MessageEntryView.js : 来自MessageEntryView.js

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

From MessageEntry.java : 来自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);
}

Attempt 3 is what did it. 尝试3是做了什么。 I just called the GWT method incorrectly from the native method. 我刚从本机方法错误地调用了GWT方法。

Using the Global namespace and extending it to use Backbone events, I just have the Backbone view trigger the Global event and the GWT view listen for the event. 使用Global命名空间并将其扩展为使用Backbone事件,我只需要Backbone视图触发Global事件,并且GWT视图侦听事件。

Attempt 3 尝试3

From MessageEntryView.js : 来自MessageEntryView.js

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

From MessageEntry.java : 来自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);
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM