##// END OF EJS Templates
Add Promise support to models.
Jonathan Frederic -
Show More
@@ -172,11 +172,19 b' define(['
172 172
173 173 WidgetManager.prototype.get_model = function (model_id) {
174 174 // Look-up a model instance by its id.
175 var model = this._models[model_id];
176 if (model !== undefined && model.id == model_id) {
177 return model;
175 var that = this;
176 var model = that._models[model_id];
177 if (model !== undefined) {
178 return new Promise(function(resolve, reject){
179 if (model instanceof Promise) {
180 model.then(resolve, reject);
181 } else {
182 resolve(model);
183 }
184 });
185 } else {
186 return undefined;
178 187 }
179 return null;
180 188 };
181 189
182 190 WidgetManager.prototype._handle_comm_open = function (comm, msg) {
@@ -213,30 +221,32 b' define(['
213 221 // widget_class: (optional) string
214 222 // Target name of the widget in the back-end.
215 223 // comm: (optional) Comm
216 return new Promise(function(resolve, reject) {
224
225 // Create a comm if it wasn't provided.
226 var comm = options.comm;
227 if (!comm) {
228 comm = this.comm_manager.new_comm('ipython.widget', {'widget_class': options.widget_class});
229 }
230
231 var that = this;
232 var model_id = comm.comm_id;
233 var promise = new Promise(function(resolve, reject) {
217 234
218 235 // Get the model type using require or through the registry.
219 236 var widget_type_name = options.model_name;
220 237 var widget_module = options.model_module;
221 var that = this;
222 238 utils.try_load(widget_type_name, widget_module, WidgetManager._model_types)
223 239 .then(function(ModelType) {
224
225 // Create a comm if it wasn't provided.
226 var comm = options.comm;
227 if (!comm) {
228 comm = that.comm_manager.new_comm('ipython.widget', {'widget_class': options.widget_class});
229 }
230
231 var model_id = comm.comm_id;
232 240 var widget_model = new ModelType(that, model_id, comm);
233 241 widget_model.on('comm:close', function () {
234 242 delete that._models[model_id];
235 243 });
236 244 that._models[model_id] = widget_model;
237 reolve(widget_model);
245 resolve(widget_model);
238 246 }, reject);
239 247 });
248 this._models[model_id] = promise;
249 return promise;
240 250 };
241 251
242 252 // Backwards compatibility.
@@ -92,11 +92,22 b' define(["widgets/js/manager",'
92 92 // Handle when a widget is updated via the python side.
93 93 this.state_lock = state;
94 94 try {
95 var that = this;
96 WidgetModel.__super__.set.apply(this, [Object.keys(state).reduce(function(obj, key) {
97 obj[key] = that._unpack_models(state[key]);
98 return obj;
99 }, {})]);
95 var state_keys = [];
96 var state_values = [];
97 for (var state_key in Object.keys(state)) {
98 if (state.hasOwnProperty(state_key)) {
99 state_keys.push(state_key);
100 state_values.push(this._unpack_models(state[state_key]));
101 }
102 }
103
104 Promise.all(state_values).then(function(promise_values){
105 var unpacked_state = {};
106 for (var i = 0; i < state_keys.length; i++) {
107 unpacked_state[state_keys[i]] = promise_values[i];
108 }
109 WidgetModel.__super__.set.apply(this, [unpacked_state]);
110 }, console.error);
100 111 } finally {
101 112 this.state_lock = null;
102 113 }
@@ -254,30 +265,42 b' define(["widgets/js/manager",'
254 265 // Replace model ids with models recursively.
255 266 var that = this;
256 267 var unpacked;
257 if ($.isArray(value)) {
258 unpacked = [];
259 _.each(value, function(sub_value, key) {
260 unpacked.push(that._unpack_models(sub_value));
261 });
262 return unpacked;
263
264 } else if (value instanceof Object) {
265 unpacked = {};
266 _.each(value, function(sub_value, key) {
267 unpacked[key] = that._unpack_models(sub_value);
268 });
269 return unpacked;
268 return new Promise(function(resolve, reject) {
270 269
271 } else if (typeof value === 'string' && value.slice(0,10) === "IPY_MODEL_") {
272 var model = this.widget_manager.get_model(value.slice(10, value.length));
273 if (model) {
274 return model;
270 if ($.isArray(value)) {
271 unpacked = [];
272 _.each(value, function(sub_value, key) {
273 unpacked.push(that._unpack_models(sub_value));
274 });
275 Promise.all(unpacked).then(resolve, reject);
276
277 } else if (value instanceof Object) {
278 unpacked_values = [];
279 unpacked_keys = [];
280 _.each(value, function(sub_value, key) {
281 unpacked_keys.push(key);
282 unpacked_values.push(that._unpack_models(sub_value));
283 });
284
285 Promise.all(unpacked_values).then(function(promise_values) {
286 unpacked = {};
287 for (var i = 0; i < unpacked_keys.length; i++) {
288 unpacked[unpacked_keys[i]] = promise_values[i];
289 }
290 resolve(unpacked);
291 }, reject);
292
293 } else if (typeof value === 'string' && value.slice(0,10) === "IPY_MODEL_") {
294 var model = this.widget_manager.get_model(value.slice(10, value.length));
295 if (model) {
296 model.then(resolve, reject);
297 } else {
298 resolve(value);
299 }
275 300 } else {
276 return value;
277 }
278 } else {
279 return value;
280 }
301 resolve(value);
302 }
303 });
281 304 },
282 305
283 306 on_some_change: function(keys, callback, context) {
@@ -322,11 +345,11 b' define(["widgets/js/manager",'
322 345 //
323 346 // -given a model and (optionally) a view name if the view name is
324 347 // not given, it defaults to the model's default view attribute.
348 var that = this;
325 349 return new Promise(function(resolve, reject) {
326 350 // TODO: this is hacky, and makes the view depend on this cell attribute and widget manager behavior
327 351 // it would be great to have the widget manager add the cell metadata
328 352 // to the subview without having to add it here.
329 var that = this;
330 353 options = $.extend({ parent: this }, options || {});
331 354
332 355 this.model.widget_manager.create_view(child_model, options).then(function(child_view) {
General Comments 0
You need to be logged in to leave comments. Login now