From 44e2043afe9bacba38b5684da0a91cae076af7c3 Mon Sep 17 00:00:00 2001 From: Jason Grout Date: Wed, 1 Jan 2014 15:54:12 -0700 Subject: [PATCH] Live updates for children automatically change container views. Since traitlets does not trigger events when list elements are changed, these changes are triggered only when the entire children element is reassigned. --- .../html/static/notebook/js/widgets/base.js | 23 ++++++++++++++++++- .../static/notebook/js/widgets/container.js | 20 +++++++++++----- .../notebook/js/widgets/multicontainer.js | 21 +++++++++++++---- 3 files changed, 53 insertions(+), 11 deletions(-) diff --git a/IPython/html/static/notebook/js/widgets/base.js b/IPython/html/static/notebook/js/widgets/base.js index 4e4a7216e..230c92675 100644 --- a/IPython/html/static/notebook/js/widgets/base.js +++ b/IPython/html/static/notebook/js/widgets/base.js @@ -186,9 +186,30 @@ function(widget_manager, underscore, backbone){ // if the view name is not given, it defaults to the model's default view attribute var child_model = this.comm_manager.comms[comm_id].model; var child_view = this.widget_manager.create_view(child_model, view_name, this.cell); - this.child_views.push(child_view); + this.child_views[comm_id] = child_view; return child_view; }, + + update_child_views: function(old_list, new_list) { + // this function takes an old list and new list of comm ids + // views in child_views that correspond to deleted ids are deleted + // views corresponding to added ids are added child_views + + // delete old views + _.each(_.difference(old_list, new_list), function(element, index, list) { + var view = this.child_views[element]; + delete this.child_views[element]; + view.remove(); + }, this); + + // add new views + _.each(_.difference(new_list, old_list), function(element, index, list) { + // this function adds the view to the child_views dictionary + this.child_view(element); + }, this); + }, + + render: function(){ // render the view. By default, this is only called the first time the view is created diff --git a/IPython/html/static/notebook/js/widgets/container.js b/IPython/html/static/notebook/js/widgets/container.js index 85cd444d8..4df9799f4 100644 --- a/IPython/html/static/notebook/js/widgets/container.js +++ b/IPython/html/static/notebook/js/widgets/container.js @@ -52,12 +52,20 @@ define(["notebook/js/widgets/base"], function(widget_manager) { render: function(){ this.$el .addClass('widget-container'); - var children = this.model.get('children'); - for(var i in children) { - var view = this.child_view(children[i]); - this.$el.append(view.$el); - } - this.update() + this.children={}; + this.update_children([], this.model.get('children')); + this.model.on('change:children', function(model, value, options) { + this.update_children(model.previous('children'), value); + }, this); + this.update() + }, + + update_children: function(old_list, new_list) { + this.$el.empty(); + this.update_child_views(old_list, new_list); + _.each(new_list, function(element, index, list) { + this.$el.append(this.child_views[element].$el); + }, this) }, update: function(){ diff --git a/IPython/html/static/notebook/js/widgets/multicontainer.js b/IPython/html/static/notebook/js/widgets/multicontainer.js index c9f8c51c9..a1fdb08b4 100644 --- a/IPython/html/static/notebook/js/widgets/multicontainer.js +++ b/IPython/html/static/notebook/js/widgets/multicontainer.js @@ -26,11 +26,24 @@ define(["notebook/js/widgets/base"], function(widget_manager){ .attr('id', guid) .addClass('accordion'); this.containers = []; - for (var i in children) { - this.add_child_view(this.child_view(children[i])) - } - + this.update_children([], this.model.get('children')); + this.model.on('change:children', function(model, value, options) { + this.update_children(model.previous('children'), value); + }, this); }, + + update_children: function(old_list, new_list) { + _.each(this.containers, function(element, index, list) { + element.remove(); + }, this); + this.containers = []; + this.update_child_views(old_list, new_list); + _.each(new_list, function(element, index, list) { + this.add_child_view(this.child_views[element]); + }, this) + }, + + update: function() { // Set tab titles var titles = this.model.get('_titles');