diff --git a/IPython/html/static/notebook/js/widget.js b/IPython/html/static/notebook/js/widget.js index 823939fac..f36da0739 100644 --- a/IPython/html/static/notebook/js/widget.js +++ b/IPython/html/static/notebook/js/widget.js @@ -32,7 +32,7 @@ define(["static/components/underscore/underscore-min.js", //-------------------------------------------------------------------- var WidgetModel = Backbone.Model.extend({ apply: function(sender) { - this.save(); + this.save(this.changedAttributes(), {patch: true}); for (var index in this.views) { var view = this.views[index]; @@ -95,7 +95,7 @@ define(["static/components/underscore/underscore-min.js", var that = this; Backbone.sync = function(method, model, options, error) { - var result = that.send_sync(method, model); + var result = that.send_sync(method, model, options); if (options.success) { options.success(result); } @@ -214,6 +214,7 @@ define(["static/components/underscore/underscore-min.js", } } } + comm.model.id = comm.comm_id; comm.model.save(); this.updating = false; } @@ -234,7 +235,7 @@ define(["static/components/underscore/underscore-min.js", } // Send widget state to python backend. - WidgetManager.prototype.send_sync = function (method, model) { + WidgetManager.prototype.send_sync = function (method, model, options) { var model_json = model.toJSON(); // Only send updated state if the state hasn't been changed during an update. @@ -250,10 +251,21 @@ define(["static/components/underscore/underscore-min.js", clear_output : $.proxy(outputarea.handle_clear_output, outputarea)} }; }; - var data = {sync_method: method, sync_data: model_json}; + + // If this is a patch operation, just send the changes. + var send_json = model_json; + if (method=='patch') { + send_json = {}; + for (var attr in options.attrs) { + send_json[attr] = options.attrs[attr]; + } + } + var data = {sync_method: method, sync_data: send_json}; comm.send(data, callbacks); } + // Since the comm is a one-way communication, assume the message + // arrived. return model_json; } diff --git a/IPython/html/widgets/widget.py b/IPython/html/widgets/widget.py index 2a36aa795..08e03c4ca 100644 --- a/IPython/html/widgets/widget.py +++ b/IPython/html/widgets/widget.py @@ -96,11 +96,10 @@ class Widget(LoggingConfigurable): ### Event handlers def _handle_msg(self, msg): - # Handle backbone sync methods + # Handle backbone sync methods CREATE, PATCH, and UPDATE sync_method = msg['content']['data']['sync_method'] sync_data = msg['content']['data']['sync_data'] - if sync_method.lower() in ['create', 'update']: - self._handle_recieve_state(sync_data) + self._handle_recieve_state(sync_data) # handles all methods def _handle_recieve_state(self, sync_data): @@ -119,7 +118,7 @@ class Widget(LoggingConfigurable): if not self._property_lock and self.comm is not None: # TODO: Validate properties. # Send new state to frontend - self.send_state() + self.send_state(key=name) def _handle_close(self): @@ -154,8 +153,15 @@ class Widget(LoggingConfigurable): return None - def send_state(self): + def send_state(self, key=None): state = {} + + # If a key is provided, just send the state of that key. + keys = [] + if key is None: + keys.extend(self.keys) + else: + keys.append(key) for key in self.keys: try: state[key] = getattr(self, key)