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');