8

半分が GWT で半分が Backbone.js のアプリケーションがあります。アプリを GWT から Backbone に移行しているので、新しいコンポーネントを追加すると、それらは Backbone にあります。また、いくつかの既存のコンポーネントを Backbone に置き換えています。

コンテナーが他の GWT コンポーネントに影響を与えることができるように、特定のイベントが発生したときに GWT コンテナーに通知できるようにする必要があるコンポーネントを置き換えようとしているコンポーネントがあります。Javascript で関数が定義されているグローバル名前空間を参照する GWT のネイティブ関数があります。この関数は Backbone コンポーネントをレンダリングするため、GWT はコンポーネント自体への参照を持っていません。

GWT でカスタム DOM イベントを定義し、バックボーン コードからそのイベントをトリガーしようとしましたが、やり方が間違っていたか、それが正しい方法ではありませんでした。

カスタム イベントを作成する際に次の質問を参照しました: How to add CSS AnimationEnd event handler to GWT widget? & GWT カスタム イベント

Backbone からカスタム イベントをトリガーし、GWT でリッスンすることを 2 回試みましたが、どちらも機能しませんでした。

GWTで「聞く」(または呼び出すなど)イベントをJavascript(Backbone.js)からトリガーする(またはコールバックなどを呼び出す)助けが必要です。

コード

2 つの試行で共通するコードは、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);
}

編集

別の試みを行いましたが、これには最初の 2 つよりもいくつかの違いがあります。名前空間を作成するときは_.extend(Namespace, Backbone.Events)、バックボーン コードがリッスンする 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);
}
4

1 に答える 1

7

試み3はそれをしたものです。ネイティブ メソッドから GWT メソッドを間違って呼び出しました。

グローバル名前空間を使用し、それをバックボーン イベントを使用するように拡張すると、バックボーン ビューでグローバル イベントをトリガーし、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);
}
于 2013-08-08T23:57:35.393 に答える