More simplifications due to promises

pull/37/head
Jason Grout 11 years ago committed by Jonathan Frederic
parent 4412c12929
commit 686e73dfdf

@ -633,6 +633,21 @@ define([
});
};
var resolve_dict = function(d) {
var keys = Object.keys(d);
var values = [];
keys.forEach(function(key) {
values.push(key);
});
return Promise.all(values).then(function(v) {
d = {};
for(var i=0; i<keys.length; i++) {
d[keys[i]] = v[i];
}
return d;
});
};
var utils = {
regex_split : regex_split,
uuid : uuid,
@ -663,6 +678,7 @@ define([
wrap_ajax_error : wrap_ajax_error,
promising_ajax : promising_ajax,
load: load,
resolve_dict: resolve_dict,
};
// Backwards compatability.

@ -66,7 +66,7 @@ define([
dummy.replaceWith(view.$el);
}
view.trigger('displayed');
}, $.proxy(console.error, console));
});
}
};

@ -9,7 +9,7 @@ define(["widgets/js/manager",
], function(widgetmanager, _, Backbone, $, IPython){
var WidgetModel = Backbone.Model.extend({
constructor: function (widget_manager, model_id, comm, init_state_callback) {
constructor: function (widget_manager, model_id, comm) {
// Constructor
//
// Creates a WidgetModel instance.
@ -20,11 +20,8 @@ define(["widgets/js/manager",
// model_id : string
// An ID unique to this model.
// comm : Comm instance (optional)
// init_state_callback : callback (optional)
// Called once when the first state message is recieved from
// the back-end.
this.widget_manager = widget_manager;
this.init_state_callback = init_state_callback;
this.state_change = Promise.resolve();
this._buffered_state_diff = {};
this.pending_msgs = 0;
this.msg_buffer = null;
@ -73,11 +70,9 @@ define(["widgets/js/manager",
var method = msg.content.data.method;
switch (method) {
case 'update':
this.set_state(msg.content.data.state);
if (this.init_state_callback) {
this.init_state_callback.apply(this, [this]);
delete this.init_state_callback;
}
this.state_change = this.state_change.then(function() {
this.set_state(msg.content.data.state);
});
break;
case 'custom':
this.trigger('msg:custom', msg.content.data.content);
@ -89,28 +84,16 @@ define(["widgets/js/manager",
},
set_state: function (state) {
var that = this;
// Handle when a widget is updated via the python side.
this.state_lock = state;
try {
var state_keys = [];
var state_values = [];
for (var state_key in Object.keys(state)) {
if (state.hasOwnProperty(state_key)) {
state_keys.push(state_key);
state_values.push(this._unpack_models(state[state_key]));
}
this._unpack_models(state).then(function(state) {
that.state_lock = state;
try {
WidgetModel.__super__.set.call(this, state);
} finally {
that.state_lock = null;
}
Promise.all(state_values).then(function(promise_values){
var unpacked_state = {};
for (var i = 0; i < state_keys.length; i++) {
unpacked_state[state_keys[i]] = promise_values[i];
}
WidgetModel.__super__.set.apply(this, [unpacked_state]);
}, $.proxy(console.error, console));
} finally {
this.state_lock = null;
}
}, $.proxy(console.error, console));
},
_handle_status: function (msg, callbacks) {
@ -265,42 +248,24 @@ define(["widgets/js/manager",
// Replace model ids with models recursively.
var that = this;
var unpacked;
return new Promise(function(resolve, reject) {
if ($.isArray(value)) {
unpacked = [];
_.each(value, function(sub_value, key) {
unpacked.push(that._unpack_models(sub_value));
});
Promise.all(unpacked).then(resolve, reject);
} else if (value instanceof Object) {
unpacked_values = [];
unpacked_keys = [];
_.each(value, function(sub_value, key) {
unpacked_keys.push(key);
unpacked_values.push(that._unpack_models(sub_value));
});
Promise.all(unpacked_values).then(function(promise_values) {
unpacked = {};
for (var i = 0; i < unpacked_keys.length; i++) {
unpacked[unpacked_keys[i]] = promise_values[i];
}
resolve(unpacked);
}, reject);
} else if (typeof value === 'string' && value.slice(0,10) === "IPY_MODEL_") {
var model = this.widget_manager.get_model(value.slice(10, value.length));
if (model) {
model.then(resolve, reject);
} else {
resolve(value);
}
} else {
resolve(value);
}
});
if ($.isArray(value)) {
unpacked = [];
_.each(value, function(sub_value, key) {
unpacked.push(that._unpack_models(sub_value));
});
return Promise.all(unpacked);
} else if (value instanceof Object) {
var unpacked = {};
_.each(value, function(sub_value, key) {
unpacked[key] = that._unpack_models(sub_value)
});
return util.resolve_dict(unpacked);
} else if (typeof value === 'string' && value.slice(0,10) === "IPY_MODEL_") {
// get_model returns a promise already
return this.widget_manager.get_model(value.slice(10, value.length));
} else {
return Promise.resolve(value);
}
},
on_some_change: function(keys, callback, context) {
@ -341,28 +306,18 @@ define(["widgets/js/manager",
},
create_child_view: function(child_model, options) {
// Create and return a child view.
//
// -given a model and (optionally) a view name if the view name is
// not given, it defaults to the model's default view attribute.
// Create and promise that resolves to a child view of a given model
var that = this;
return new Promise(function(resolve, reject) {
// 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 || {});
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] = [];
}
that.child_model_views[child_model.id].push(child_view.id);
// Remember the view by id.
that.child_views[child_view.id] = child_view;
resolve(child_view);
}, reject);
options = $.extend({ parent: this }, options || {});
return 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] = [];
}
that.child_model_views[child_model.id].push(child_view.id);
// Remember the view by id.
that.child_views[child_view.id] = child_view;
return child_view;
});
},

@ -78,13 +78,13 @@ define([
var dummy = $('<div/>');
that.$box.append(dummy);
this.create_child_view(model).then(function(view) {
dummy.replaceWith(view.$el);
dummy.replaceWith(view.el);
// Trigger the displayed event of the child view.
that.after_displayed(function() {
view.trigger('displayed');
});
}, $.proxy(console.error, console));
});
},
});

Loading…
Cancel
Save