Remove the automatic _children_attr and _children_lists_attr.

When serializing, any Widget object is encoded as its comm_id.  The view should know how to deal with the attribute, and should know that the attribute is a comm_id.
Jason Grout 12 years ago committed by Jonathan Frederic
parent ad1e23bfc2
commit 72f7d2fe09

@ -230,35 +230,14 @@ function(widget_manager, underscore, backbone){
this.widget_manager = options.widget_manager;
this.comm_manager = options.widget_manager.comm_manager;
this.cell = options.cell
this.render();
// jng: maybe the following shouldn't be automatic---maybe the render method should take
// care of knowing what needs to be added as a child?
var children_attr = this.model.get('_children_attr');
for (var i in children_attr) {
var child_attr = children_attr[i];
var child_model = this.comm_manager.comms[this.model.get(child_attr)].model;
var child_view_name = this.child_view_name(child_attr, child_model);
var child_view = this.widget_manager.create_view(child_model, child_view_name, this.cell);
this.add_child_view(child_attr, child_view);
}
var children_lists_attr = this.model.get('_children_lists_attr')
for (var i in children_lists_attr) {
var child_attr = children_lists_attr[i];
var child_list = this.model.get(child_attr);
for (var j in child_list) {
var child_model = this.comm_manager.comms[child_list[j]].model;
var child_view_name = this.child_view_name(child_attr, child_model);
var child_view = this.widget_manager.create_view(child_model, child_view_name, this.cell);
this.add_child_view(child_attr, child_view);
}
}
},
update: function(){
// update thyself to be consistent with this.model
},
child_view: function(attr, viewname) {
var child_model = this.comm_manager.comms[this.model.get(attr)].model;
child_view: function(comm_id, view_name) {
var child_model = this.comm_manager.comms[comm_id].model;
var child_view = this.widget_manager.create_view(child_model, view_name, this.cell);
return child_view;
},
@ -266,19 +245,6 @@ function(widget_manager, underscore, backbone){
render: function(){
// render thyself
},
child_view_name: function(attr, model) {
// attr is the name of the attribute we are constructing a view for
// model is the model stored in that attribute
// return a valid view_name to construct a view of that type
// or null for the default view for the model
return null;
},
add_child_view: function(attr, view) {
//attr is the name of the attribute containing a reference to this child
//view is the child view that has been constructed
//typically this will just add the child view's view.el attribute to some dom element
},
send: function (content) {
this.model.send(content, this.model.cell_callbacks(this.cell));
},
@ -287,8 +253,6 @@ function(widget_manager, underscore, backbone){
this.model.last_modified_view = this;
this.model.save(this.model.changedAttributes(), {patch: true});
},
});
var WidgetView = BaseWidgetView.extend({

@ -52,9 +52,11 @@ 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 this.model.get('children')) {
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()
},
@ -62,11 +64,6 @@ define(["notebook/js/widgets/base"], function(widget_manager) {
set_flex_properties(this, this.$el);
return IPython.WidgetView.prototype.update.call(this);
},
add_child_view: function(attr, view) {
if (attr==='children') {
this.$el.append(view.$el);
}
}
});
widget_manager.register_widget_view('ContainerView', ContainerView);

@ -118,6 +118,10 @@ define(["notebook/js/widgets/base"], function(widget_manager){
this.$tab_contents = $('<div />', {id: uuid + 'Content'})
.addClass('tab-content')
.appendTo(this.$el);
var children = this.model.get('children');
for (var i in children) {
this.add_child_view(this.child_view(children[i]))
}
this.update();
},
@ -139,8 +143,7 @@ define(["notebook/js/widgets/base"], function(widget_manager){
return IPython.WidgetView.prototype.update.call(this);
},
add_child_view: function(attr, view) {
console.log('adding child view', attr, view);
add_child_view: function(view) {
var index = this.containers.length;
var uuid = IPython.utils.uuid();
@ -165,11 +168,6 @@ define(["notebook/js/widgets/base"], function(widget_manager){
.addClass('fade')
.append(view.$el)
.appendTo(this.$tab_contents);
if (index === 0) {
tab_text.tab('show');
}
this.update();
},
select_page: function(index) {

@ -75,7 +75,7 @@ define(["notebook/js/widgets/base"], function(widget_manager){
this.$el_to_style = this.$textbox; // Set default element to style
this.update(); // Set defaults.
this.model.on_msg($.proxy(this._handle_textarea_msg, this));
this.model.on('msg:custom', $.proxy(this._handle_textarea_msg, this));
},

@ -36,11 +36,6 @@ class BaseWidget(LoggingConfigurable):
# Shared declarations (Class level)
_keys = List(Unicode, default_value = [],
help="List of keys comprising the state of the model.", allow_none=False)
_children_attr = List(Unicode, default_value = [],
help="List of keys of children objects of the model.", allow_none=False)
_children_lists_attr = List(Unicode, default_value = [],
help="List of keys containing lists of children objects of the model.",
allow_none=False)
widget_construction_callback = None
def on_widget_constructed(callback):
@ -78,7 +73,7 @@ class BaseWidget(LoggingConfigurable):
# Register after init to allow default values to be specified
# TODO: register three different handlers, one for each list, and abstract out the common parts
#print self.keys, self._children_attr, self._children_lists_attr
self.on_trait_change(self._handle_property_changed, self.keys+self._children_attr+self._children_lists_attr)
self.on_trait_change(self._handle_property_changed, self.keys)
Widget._handle_widget_constructed(self)
def __del__(self):
@ -96,7 +91,7 @@ class BaseWidget(LoggingConfigurable):
# Properties
@property
def keys(self):
keys = ['_children_attr', '_children_lists_attr', 'default_view_name']
keys = ['default_view_name']
keys.extend(self._keys)
return keys
@ -215,26 +210,22 @@ class BaseWidget(LoggingConfigurable):
# If a key is provided, just send the state of that key.
if key is None:
keys = self.keys[:]
children_attr = self._children_attr[:]
children_lists_attr = self._children_lists_attr[:]
else:
keys = []
children_attr = []
children_lists_attr = []
if key in self._children_attr:
children_attr.append(key)
elif key in self._children_lists_attr:
children_lists_attr.append(key)
else:
keys.append(key)
keys = [key]
for k in keys:
state[k] = getattr(self, k)
for k in children_attr:
# automatically create models on the browser side if they aren't already created
state[k] = getattr(self, k).comm.comm_id
for k in children_lists_attr:
# automatically create models on the browser side if they aren't already created
state[k] = [i.comm.comm_id for i in getattr(self, k)]
value = getattr(self, k)
# a more elegant solution to encoding BaseWidgets would be
# to tap into the JSON encoder and teach it how to deal
# with BaseWidget objects, or maybe just teach the JSON
# encoder to look for a _repr_json property before giving
# up encoding
if isinstance(value, BaseWidget):
value = value.comm.comm_id
elif isinstance(value, list) and isinstance(value[0], BaseWidget):
# assume all elements of the list are widgets
value = [i.comm.comm_id for i in value]
state[k] = value
return state

Loading…
Cancel
Save