mirror of
https://github.com/jupyter/notebook.git
synced 2025-01-24 12:05:22 +08:00
Initial stab at adding promises to the widget framework.
This commit is contained in:
parent
ff680583c1
commit
4beda5d0fb
@ -605,6 +605,33 @@ define([
|
||||
$.ajax(url, settings);
|
||||
});
|
||||
};
|
||||
|
||||
var try_load = function(class_name, module_name, registry) {
|
||||
// Tries to load a class
|
||||
//
|
||||
// Tries to load a class from a module using require.js, if a module
|
||||
// is specified, otherwise tries to load a class from the global
|
||||
// registry, if the global registry is provided.
|
||||
return new Promise(function(resolve, reject) {
|
||||
|
||||
// Try loading the view module using require.js
|
||||
if (module_name) {
|
||||
require([module_name], function(module) {
|
||||
if (module[class_name] === undefined) {
|
||||
reject(Error('Class not found in module.'));
|
||||
} else {
|
||||
resolve(module[class_name]);
|
||||
}
|
||||
}, reject);
|
||||
} else {
|
||||
if (registry && registry[class_name]) {
|
||||
resolve(registry[class_name]);
|
||||
} else {
|
||||
reject(Error('Class not found in registry.'));
|
||||
}
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
var utils = {
|
||||
regex_split : regex_split,
|
||||
@ -635,6 +662,7 @@ define([
|
||||
XHR_ERROR : XHR_ERROR,
|
||||
wrap_ajax_error : wrap_ajax_error,
|
||||
promising_ajax : promising_ajax,
|
||||
try_load: try_load,
|
||||
};
|
||||
|
||||
// Backwards compatability.
|
||||
|
@ -5,8 +5,9 @@ define([
|
||||
"underscore",
|
||||
"backbone",
|
||||
"jquery",
|
||||
"base/js/utils",
|
||||
"base/js/namespace"
|
||||
], function (_, Backbone, $, IPython) {
|
||||
], function (_, Backbone, $, utils, IPython) {
|
||||
"use strict";
|
||||
//--------------------------------------------------------------------
|
||||
// WidgetManager class
|
||||
@ -52,14 +53,20 @@ define([
|
||||
console.log("Could not determine where the display" +
|
||||
" message was from. Widget will not be displayed");
|
||||
} else {
|
||||
var dummy = null;
|
||||
if (cell.widget_subarea) {
|
||||
dummy = $('<div />');
|
||||
cell.widget_subarea.append(dummy);
|
||||
}
|
||||
|
||||
var that = this;
|
||||
this.create_view(model, {cell: cell, success: function(view) {
|
||||
this.create_view(model, {cell: cell}).then(function(view) {
|
||||
that._handle_display_view(view);
|
||||
if (cell.widget_subarea) {
|
||||
cell.widget_subarea.append(view.$el);
|
||||
if (dummy) {
|
||||
dummy.replaceWith(view.$el);
|
||||
}
|
||||
view.trigger('displayed');
|
||||
}});
|
||||
}, function(error) { console.error(error); });
|
||||
}
|
||||
};
|
||||
|
||||
@ -70,30 +77,25 @@ define([
|
||||
if (this.keyboard_manager) {
|
||||
this.keyboard_manager.register_events(view.$el);
|
||||
|
||||
if (view.additional_elements) {
|
||||
for (var i = 0; i < view.additional_elements.length; i++) {
|
||||
this.keyboard_manager.register_events(view.additional_elements[i]);
|
||||
}
|
||||
}
|
||||
if (view.additional_elements) {
|
||||
for (var i = 0; i < view.additional_elements.length; i++) {
|
||||
this.keyboard_manager.register_events(view.additional_elements[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
WidgetManager.prototype.create_view = function(model, options) {
|
||||
// Creates a view for a particular model.
|
||||
|
||||
var view_name = model.get('_view_name');
|
||||
var view_mod = model.get('_view_module');
|
||||
var options = options || {};
|
||||
|
||||
return new Promise(function(resolve, reject) {
|
||||
var instantiate_view = function(ViewType) {
|
||||
if (ViewType === undefined) {
|
||||
reject(Error("Unknown view, module: "+view_mod+", view: "+view_name));
|
||||
}
|
||||
var view_name = model.get('_view_name');
|
||||
var view_module = model.get('_view_module');
|
||||
utils.try_load(view_name, view_module, WidgetManager._view_types).then(function(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 (options.parent !== undefined) {
|
||||
options.cell = options.parent.options.cell;
|
||||
}
|
||||
@ -102,19 +104,10 @@ define([
|
||||
var parameters = {model: model, options: options};
|
||||
var view = new ViewType(parameters);
|
||||
view.render();
|
||||
view.listenTo(model, 'destroy', view.remove);
|
||||
model.on('destroy', view.remove, view);
|
||||
resolve(view);
|
||||
};
|
||||
|
||||
|
||||
if (view_mod) {
|
||||
require([view_mod], function(module) {
|
||||
instantiate_view(module[view_name]);
|
||||
}, reject);
|
||||
} else {
|
||||
instantiate_view(WidgetManager._view_types[view_name]);
|
||||
}
|
||||
}
|
||||
}, reject);
|
||||
});
|
||||
};
|
||||
|
||||
WidgetManager.prototype.get_msg_cell = function (msg_id) {
|
||||
@ -205,8 +198,9 @@ define([
|
||||
// JS:
|
||||
// IPython.notebook.kernel.widget_manager.create_model({
|
||||
// model_name: 'WidgetModel',
|
||||
// widget_class: 'IPython.html.widgets.widget_int.IntSlider',
|
||||
// init_state_callback: function(model) { console.log('Create success!', model); }});
|
||||
// widget_class: 'IPython.html.widgets.widget_int.IntSlider'})
|
||||
// .then(function(model) { console.log('Create success!', model); },
|
||||
// function(error) { console.error(error); });
|
||||
//
|
||||
// Parameters
|
||||
// ----------
|
||||
@ -219,50 +213,33 @@ define([
|
||||
// widget_class: (optional) string
|
||||
// Target name of the widget in the back-end.
|
||||
// comm: (optional) Comm
|
||||
// init_state_callback: (optional) callback
|
||||
// Called when the first state push from the back-end is
|
||||
// recieved. Allows you to modify the model after it's
|
||||
// complete state is filled and synced.
|
||||
|
||||
// Create a comm if it wasn't provided.
|
||||
var comm = options.comm;
|
||||
if (!comm) {
|
||||
comm = this.comm_manager.new_comm('ipython.widget', {'widget_class': options.widget_class});
|
||||
}
|
||||
|
||||
return new Promise(function(resolve, reject) {
|
||||
// Create a new model that is connected to the comm.
|
||||
var that = this;
|
||||
var instantiate_model = function(ModelType) {
|
||||
if (ModelType === undefined) {
|
||||
reject(Error("Error creating widget model: " + widget_type_name
|
||||
+ " not found in " + widget_module));
|
||||
}
|
||||
var model_id = comm.comm_id;
|
||||
var widget_model = new ModelType(that, model_id, comm, options.init_state_callback);
|
||||
widget_model.once('comm:close', function () {
|
||||
delete that._models[model_id];
|
||||
});
|
||||
that._models[model_id] = widget_model;
|
||||
resolve(widget_model);
|
||||
};
|
||||
|
||||
|
||||
// Get the model type using require or through the registry.
|
||||
var widget_type_name = options.model_name;
|
||||
var widget_module = options.model_module;
|
||||
if (widget_module) {
|
||||
// Load the module containing the widget model
|
||||
require([widget_module], function(mod) {
|
||||
instantiate_model(mod[widget_type_name]);
|
||||
var that = this;
|
||||
utils.try_load(widget_type_name, widget_module, WidgetManager._model_types)
|
||||
.then(function(ModelType) {
|
||||
|
||||
// Create a comm if it wasn't provided.
|
||||
var comm = options.comm;
|
||||
if (!comm) {
|
||||
comm = that.comm_manager.new_comm('ipython.widget', {'widget_class': options.widget_class});
|
||||
}
|
||||
|
||||
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;
|
||||
reolve(widget_model);
|
||||
}, reject);
|
||||
} else {
|
||||
// No module specified, load from the global models registry
|
||||
instantiate_model(WidgetManager._model_types[widget_type_name]);
|
||||
}
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
// Backwards compatability.
|
||||
// Backwards compatibility.
|
||||
IPython.WidgetManager = WidgetManager;
|
||||
|
||||
return {'WidgetManager': WidgetManager};
|
||||
|
@ -328,7 +328,9 @@ define(["widgets/js/manager",
|
||||
// to the subview without having to add it here.
|
||||
var that = this;
|
||||
var old_callback = options.callback || function(view) {};
|
||||
options = $.extend({ parent: this, success: function(child_view) {
|
||||
options = $.extend({ parent: this }, options || {});
|
||||
|
||||
this.model.widget_manager.create_view(child_model, options).then(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] = [];
|
||||
@ -338,9 +340,7 @@ define(["widgets/js/manager",
|
||||
// Remember the view by id.
|
||||
that.child_views[child_view.id] = child_view;
|
||||
old_callback(child_view);
|
||||
}}, options || {});
|
||||
|
||||
this.model.widget_manager.create_view(child_model, options);
|
||||
}, function(error) { console.error(error); });
|
||||
},
|
||||
|
||||
pop_child_view: function(child_model) {
|
||||
|
@ -18,12 +18,11 @@ casper.notebook_test(function () {
|
||||
this.evaluate(function() {
|
||||
IPython.notebook.kernel.widget_manager.create_model({
|
||||
model_name: 'WidgetModel',
|
||||
widget_class: 'IPython.html.widgets.widget_int.IntSlider',
|
||||
init_state_callback: function(model) {
|
||||
widget_class: 'IPython.html.widgets.widget_int.IntSlider'})
|
||||
.then(function(model) {
|
||||
console.log('Create success!', model);
|
||||
window.slider_id = model.id;
|
||||
}
|
||||
});
|
||||
}, function(error) { console.log(error); });
|
||||
});
|
||||
});
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user