Allow widget views to be loaded from require modules

This required refactoring things that create widget views to use
callbacks instead of return values.
Thomas Kluyver 12 years ago
parent e808d23594
commit 5953a3f874

@ -63,15 +63,17 @@ define([
console.log("Could not determine where the display" +
" message was from. Widget will not be displayed");
} else {
var view = this.create_view(model, {cell: cell});
if (view === null) {
console.error("View creation failed", model);
}
this._handle_display_view(view);
if (cell.widget_subarea) {
cell.widget_subarea.append(view.$el);
}
view.trigger('displayed');
var that = this;
this.create_view(model, {cell: cell, callback: function(view) {
if (view === null) {
console.error("View creation failed", model);
}
that._handle_display_view(view);
if (cell.widget_subarea) {
cell.widget_subarea.append(view.$el);
}
view.trigger('displayed');
}});
}
};
@ -89,28 +91,38 @@ define([
}
}
};
WidgetManager.prototype.create_view = function(model, options, view) {
// Creates a view for a particular model.
var view_name = model.get('_view_name');
var ViewType = WidgetManager._view_types[view_name];
if (ViewType) {
// If a view is passed into the method, use that view's cell as
// the cell for the view that is created.
options = options || {};
if (view !== undefined) {
options.cell = view.options.cell;
var instantiate_view = function(ViewType) {
if (ViewType) {
// If a view is passed into the method, use that view's cell as
// the cell for the view that is created.
options = options || {};
if (view !== undefined) {
options.cell = view.options.cell;
}
// Create and render the view...
var parameters = {model: model, options: options};
view = new ViewType(parameters);
view.render();
model.on('destroy', view.remove, view);
options.callback(view);
}
// Create and render the view...
var parameters = {model: model, options: options};
view = new ViewType(parameters);
view.render();
model.on('destroy', view.remove, view);
return view;
}
return null;
var view_name = model.get('_view_name');
var view_mod = model.get('_view_module');
if (view_mod !== '') {
console.log(view_mod);
require([view_mod], function(module) {
instantiate_view(module[view_name])
});
} else {
instantiate_view(WidgetManager._view_types[view_name]);
}
};
WidgetManager.prototype.get_msg_cell = function (msg_id) {

@ -308,7 +308,7 @@ define(["widgets/js/manager",
// Update view to be consistent with this.model
},
create_child_view: function(child_model, options) {
create_child_view: function(child_model, callback, options) {
// Create and return a child view.
//
// -given a model and (optionally) a view name if the view name is
@ -317,18 +317,20 @@ define(["widgets/js/manager",
// TODO: this is hacky, and makes the view depend on this cell attribute and widget manager behavior
// it would be great to have the widget manager add the cell metadata
// to the subview without having to add it here.
options = $.extend({ parent: this }, options || {});
var child_view = this.model.widget_manager.create_view(child_model, options, this);
// Associate the view id with the model id.
if (this.child_model_views[child_model.id] === undefined) {
this.child_model_views[child_model.id] = [];
}
this.child_model_views[child_model.id].push(child_view.id);
var that = this;
options = $.extend({ parent: this, callback: function(child_view) {
// Associate the view id with the model id.
if (that.child_model_views[child_model.id] === undefined) {
that.child_model_views[child_model.id] = [];
}
that.child_model_views[child_model.id].push(child_view.id);
// Remember the view by id.
this.child_views[child_view.id] = child_view;
return child_view;
// Remember the view by id.
that.child_views[child_view.id] = child_view;
callback(child_view);
}}, options || {});
this.model.widget_manager.create_view(child_model, options, this);
},
pop_child_view: function(child_model) {

@ -74,12 +74,14 @@ define([
add_child_model: function(model) {
// Called when a model is added to the children list.
var view = this.create_child_view(model);
this.$box.append(view.$el);
var that = this;
this.create_child_view(model, function(view) {
that.$box.append(view.$el);
// Trigger the displayed event of the child view.
this.after_displayed(function() {
view.trigger('displayed');
// Trigger the displayed event of the child view.
that.after_displayed(function() {
view.trigger('displayed');
});
});
},
});

@ -81,7 +81,6 @@ define([
add_child_model: function(model) {
// Called when a child is added to children list.
var view = this.create_child_view(model);
var index = this.containers.length;
var uuid = utils.uuid();
var accordion_group = $('<div />')
@ -114,14 +113,17 @@ define([
var container_index = this.containers.push(accordion_group) - 1;
accordion_group.container_index = container_index;
this.model_containers[model.id] = accordion_group;
accordion_inner.append(view.$el);
this.create_child_view(model, function(view) {
accordion_inner.append(view.$el);
this.update();
this.update_titles();
that.update();
that.update_titles();
// Trigger the displayed event of the child view.
this.after_displayed(function() {
view.trigger('displayed');
// Trigger the displayed event of the child view.
that.after_displayed(function() {
view.trigger('displayed');
});
});
},
});
@ -176,7 +178,6 @@ define([
add_child_model: function(model) {
// Called when a child is added to children list.
var view = this.create_child_view(model);
var index = this.containers.length;
var uuid = utils.uuid();
@ -184,33 +185,36 @@ define([
var tab = $('<li />')
.css('list-style-type', 'none')
.appendTo(this.$tabs);
view.parent_tab = tab;
var tab_text = $('<a />')
.attr('href', '#' + uuid)
.attr('data-toggle', 'tab')
.text('Page ' + index)
.appendTo(tab)
.click(function (e) {
// Calling model.set will trigger all of the other views of the
// model to update.
that.model.set("selected_index", index, {updated_view: this});
that.touch();
that.select_page(index);
this.create_child_view(model, function(view) {
view.parent_tab = tab;
var tab_text = $('<a />')
.attr('href', '#' + uuid)
.attr('data-toggle', 'tab')
.text('Page ' + index)
.appendTo(tab)
.click(function (e) {
// Calling model.set will trigger all of the other views of the
// model to update.
that.model.set("selected_index", index, {updated_view: that});
that.touch();
that.select_page(index);
});
tab.tab_text_index = that.containers.push(tab_text) - 1;
var contents_div = $('<div />', {id: uuid})
.addClass('tab-pane')
.addClass('fade')
.append(view.$el)
.appendTo(that.$tab_contents);
view.parent_container = contents_div;
// Trigger the displayed event of the child view.
that.after_displayed(function() {
view.trigger('displayed');
});
tab.tab_text_index = this.containers.push(tab_text) - 1;
var contents_div = $('<div />', {id: uuid})
.addClass('tab-pane')
.addClass('fade')
.append(view.$el)
.appendTo(this.$tab_contents);
view.parent_container = contents_div;
// Trigger the displayed event of the child view.
this.after_displayed(function() {
view.trigger('displayed');
});
},

@ -100,6 +100,8 @@ class Widget(LoggingConfigurable):
#-------------------------------------------------------------------------
_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.
If empty, look in the global registry.""", sync=True)
_view_name = Unicode(None, allow_none=True, help="""Default view registered in the front-end
to use to represent the widget.""", sync=True)
comm = Instance('IPython.kernel.comm.Comm')

Loading…
Cancel
Save