半分が 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);
}