diff --git a/IPython/html/static/services/kernels/comm.js b/IPython/html/static/services/kernels/comm.js
index 91f3dc826..f25517b82 100644
--- a/IPython/html/static/services/kernels/comm.js
+++ b/IPython/html/static/services/kernels/comm.js
@@ -65,20 +65,40 @@ define([
CommManager.prototype.comm_open = function (msg) {
var content = msg.content;
- var f = this.targets[content.target_name];
- if (f === undefined) {
- console.log("No such target registered: ", content.target_name);
- console.log("Available targets are: ", this.targets);
- return;
- }
- var comm = new Comm(content.target_name, content.comm_id);
- this.register_comm(comm);
- try {
- f(comm, msg);
- } catch (e) {
- console.log("Exception opening new comm:", e, e.stack, msg);
- comm.close();
- this.unregister_comm(comm);
+ var that = this;
+
+ var instantiate_comm = function(target) {
+ var comm = new Comm(content.target_name, content.comm_id);
+ that.register_comm(comm);
+ try {
+ target(comm, msg);
+ } catch (e) {
+ console.log("Exception opening new comm:", e, e.stack, msg);
+ comm.close();
+ that.unregister_comm(comm);
+ }
+ };
+
+ if (content.target_module) {
+ // Load requirejs module for comm target
+ require([content.target_module], function(mod) {
+ var target = mod[content.target_name];
+ if (target !== undefined) {
+ instantiate_comm(target)
+ } else {
+ console.log("Comm target " + content.target_name +
+ " not found in module " + content.target_module);
+ }
+ }, function(err) { console.log(err); });
+ } else {
+ // No requirejs module specified: look for target in registry
+ var f = this.targets[content.target_name];
+ if (f === undefined) {
+ console.log("No such target registered: ", content.target_name);
+ console.log("Available targets are: ", this.targets);
+ return;
+ }
+ instantiate_comm(f)
}
};
diff --git a/IPython/html/static/widgets/js/manager.js b/IPython/html/static/widgets/js/manager.js
index dd3472c52..944effd5a 100644
--- a/IPython/html/static/widgets/js/manager.js
+++ b/IPython/html/static/widgets/js/manager.js
@@ -188,13 +188,33 @@ define([
WidgetManager.prototype._handle_comm_open = function (comm, msg) {
// Handle when a comm is opened.
var that = this;
- var model_id = comm.comm_id;
+
+ var instantiate_model = function(ModelType) {
+ var model_id = comm.comm_id;
+ var widget_model = new ModelType(that, model_id, comm);
+ widget_model.on('comm:close', function () {
+ delete that._models[model_id];
+ });
+ that._models[model_id] = widget_model;
+ };
+
var widget_type_name = msg.content.data.model_name;
- var widget_model = new WidgetManager._model_types[widget_type_name](this, model_id, comm);
- widget_model.on('comm:close', function () {
- delete that._models[model_id];
- });
- this._models[model_id] = widget_model;
+ var widget_module = msg.content.data.model_module;
+
+ if (widget_module) {
+ // Load the module containing the widget model
+ require([widget_module], function(mod) {
+ if (mod[widget_type_name]) {
+ instantiate_model(mod[widget_type_name]);
+ } else {
+ console.log("Error creating widget model: " + widget_type_name
+ + " not found in " + widget_module);
+ }
+ }, function(err) { console.log(err); });
+ } else {
+ // No module specified, load from the global models registry
+ instantiate_model(WidgetManager._model_types[widget_type_name]);
+ }
};
// Backwards compatability.
diff --git a/IPython/html/widgets/widget.py b/IPython/html/widgets/widget.py
index 86e85aa82..f1571eab4 100644
--- a/IPython/html/widgets/widget.py
+++ b/IPython/html/widgets/widget.py
@@ -98,6 +98,8 @@ class Widget(LoggingConfigurable):
#-------------------------------------------------------------------------
# Traits
#-------------------------------------------------------------------------
+ _model_module = Unicode(None, allow_none=True, help="""A requirejs module name
+ in which to find _model_name. If empty, look in the global registry.""")
_model_name = Unicode('WidgetModel', help="""Name of the backbone model
registered in the front-end to create and sync this widget with.""")
_view_module = Unicode(help="""A requirejs module in which to find _view_name.
@@ -142,7 +144,9 @@ class Widget(LoggingConfigurable):
def open(self):
"""Open a comm to the frontend if one isn't already open."""
if self.comm is None:
- args = dict(target_name='ipython.widget', data={ 'model_name': self._model_name })
+ args = dict(target_name='ipython.widget',
+ data={'model_name': self._model_name,
+ 'model_module': self._model_module})
if self._model_id is not None:
args['comm_id'] = self._model_id
self.comm = Comm(**args)