我有一个一半是 GWT 一半是 Backbone.js 的应用程序。我们正在将应用程序从 GWT 过渡到 Backbone,因此当我们添加新组件时,它们就在 Backbone 中。我们还用 Backbone 替换了一些现有组件。
我正在尝试替换一个组件,它仍然需要能够让其 GWT 容器知道何时发生某些事件,以便容器可以影响其他 GWT 组件。我在 GWT 中有一个本机函数,它引用了一个全局命名空间,在该命名空间上用 Javascript 定义了一个函数。该函数呈现 Backbone 组件,因此 GWT 没有对组件本身的引用。
我尝试在 GWT 中定义一个自定义 DOM 事件,然后从 Backbone 代码触发该事件,但要么我做错了,要么这不是方法。
我在创建自定义事件时引用了这些问题:如何将 CSS AnimationEnd 事件处理程序添加到 GWT 小部件?& GWT 自定义事件
我做了两次尝试从 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)
做是为了从 GWT 触发 Backbone 代码将侦听的事件。我决定尝试让它朝另一个方向工作。它没有。
尝试 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);
}