##// END OF EJS Templates
Allow widget views to be loaded from require modules...
Thomas Kluyver -
Show More
@@ -63,15 +63,17 b' define(['
63 console.log("Could not determine where the display" +
63 console.log("Could not determine where the display" +
64 " message was from. Widget will not be displayed");
64 " message was from. Widget will not be displayed");
65 } else {
65 } else {
66 var view = this.create_view(model, {cell: cell});
66 var that = this;
67 if (view === null) {
67 this.create_view(model, {cell: cell, callback: function(view) {
68 console.error("View creation failed", model);
68 if (view === null) {
69 }
69 console.error("View creation failed", model);
70 this._handle_display_view(view);
70 }
71 if (cell.widget_subarea) {
71 that._handle_display_view(view);
72 cell.widget_subarea.append(view.$el);
72 if (cell.widget_subarea) {
73 }
73 cell.widget_subarea.append(view.$el);
74 view.trigger('displayed');
74 }
75 view.trigger('displayed');
76 }});
75 }
77 }
76 };
78 };
77
79
@@ -89,28 +91,38 b' define(['
89 }
91 }
90 }
92 }
91 };
93 };
94
92
95
93 WidgetManager.prototype.create_view = function(model, options, view) {
96 WidgetManager.prototype.create_view = function(model, options, view) {
94 // Creates a view for a particular model.
97 // Creates a view for a particular model.
95 var view_name = model.get('_view_name');
98 var instantiate_view = function(ViewType) {
96 var ViewType = WidgetManager._view_types[view_name];
99 if (ViewType) {
97 if (ViewType) {
100 // If a view is passed into the method, use that view's cell as
98
101 // the cell for the view that is created.
99 // If a view is passed into the method, use that view's cell as
102 options = options || {};
100 // the cell for the view that is created.
103 if (view !== undefined) {
101 options = options || {};
104 options.cell = view.options.cell;
102 if (view !== undefined) {
105 }
103 options.cell = view.options.cell;
106
107 // Create and render the view...
108 var parameters = {model: model, options: options};
109 view = new ViewType(parameters);
110 view.render();
111 model.on('destroy', view.remove, view);
112 options.callback(view);
104 }
113 }
105
106 // Create and render the view...
107 var parameters = {model: model, options: options};
108 view = new ViewType(parameters);
109 view.render();
110 model.on('destroy', view.remove, view);
111 return view;
112 }
114 }
113 return null;
115
116 var view_name = model.get('_view_name');
117 var view_mod = model.get('_view_module');
118 if (view_mod !== '') {
119 console.log(view_mod);
120 require([view_mod], function(module) {
121 instantiate_view(module[view_name])
122 });
123 } else {
124 instantiate_view(WidgetManager._view_types[view_name]);
125 }
114 };
126 };
115
127
116 WidgetManager.prototype.get_msg_cell = function (msg_id) {
128 WidgetManager.prototype.get_msg_cell = function (msg_id) {
@@ -308,7 +308,7 b' define(["widgets/js/manager",'
308 // Update view to be consistent with this.model
308 // Update view to be consistent with this.model
309 },
309 },
310
310
311 create_child_view: function(child_model, options) {
311 create_child_view: function(child_model, callback, options) {
312 // Create and return a child view.
312 // Create and return a child view.
313 //
313 //
314 // -given a model and (optionally) a view name if the view name is
314 // -given a model and (optionally) a view name if the view name is
@@ -317,18 +317,20 b' define(["widgets/js/manager",'
317 // TODO: this is hacky, and makes the view depend on this cell attribute and widget manager behavior
317 // TODO: this is hacky, and makes the view depend on this cell attribute and widget manager behavior
318 // it would be great to have the widget manager add the cell metadata
318 // it would be great to have the widget manager add the cell metadata
319 // to the subview without having to add it here.
319 // to the subview without having to add it here.
320 options = $.extend({ parent: this }, options || {});
320 var that = this;
321 var child_view = this.model.widget_manager.create_view(child_model, options, this);
321 options = $.extend({ parent: this, callback: function(child_view) {
322
322 // Associate the view id with the model id.
323 // Associate the view id with the model id.
323 if (that.child_model_views[child_model.id] === undefined) {
324 if (this.child_model_views[child_model.id] === undefined) {
324 that.child_model_views[child_model.id] = [];
325 this.child_model_views[child_model.id] = [];
325 }
326 }
326 that.child_model_views[child_model.id].push(child_view.id);
327 this.child_model_views[child_model.id].push(child_view.id);
328
327
329 // Remember the view by id.
328 // Remember the view by id.
330 this.child_views[child_view.id] = child_view;
329 that.child_views[child_view.id] = child_view;
331 return child_view;
330 callback(child_view);
331 }}, options || {});
332
333 this.model.widget_manager.create_view(child_model, options, this);
332 },
334 },
333
335
334 pop_child_view: function(child_model) {
336 pop_child_view: function(child_model) {
@@ -74,12 +74,14 b' define(['
74
74
75 add_child_model: function(model) {
75 add_child_model: function(model) {
76 // Called when a model is added to the children list.
76 // Called when a model is added to the children list.
77 var view = this.create_child_view(model);
77 var that = this;
78 this.$box.append(view.$el);
78 this.create_child_view(model, function(view) {
79 that.$box.append(view.$el);
79
80
80 // Trigger the displayed event of the child view.
81 // Trigger the displayed event of the child view.
81 this.after_displayed(function() {
82 that.after_displayed(function() {
82 view.trigger('displayed');
83 view.trigger('displayed');
84 });
83 });
85 });
84 },
86 },
85 });
87 });
@@ -81,7 +81,6 b' define(['
81
81
82 add_child_model: function(model) {
82 add_child_model: function(model) {
83 // Called when a child is added to children list.
83 // Called when a child is added to children list.
84 var view = this.create_child_view(model);
85 var index = this.containers.length;
84 var index = this.containers.length;
86 var uuid = utils.uuid();
85 var uuid = utils.uuid();
87 var accordion_group = $('<div />')
86 var accordion_group = $('<div />')
@@ -114,14 +113,17 b' define(['
114 var container_index = this.containers.push(accordion_group) - 1;
113 var container_index = this.containers.push(accordion_group) - 1;
115 accordion_group.container_index = container_index;
114 accordion_group.container_index = container_index;
116 this.model_containers[model.id] = accordion_group;
115 this.model_containers[model.id] = accordion_group;
117 accordion_inner.append(view.$el);
116
117 this.create_child_view(model, function(view) {
118 accordion_inner.append(view.$el);
118
119
119 this.update();
120 that.update();
120 this.update_titles();
121 that.update_titles();
121
122
122 // Trigger the displayed event of the child view.
123 // Trigger the displayed event of the child view.
123 this.after_displayed(function() {
124 that.after_displayed(function() {
124 view.trigger('displayed');
125 view.trigger('displayed');
126 });
125 });
127 });
126 },
128 },
127 });
129 });
@@ -176,7 +178,6 b' define(['
176
178
177 add_child_model: function(model) {
179 add_child_model: function(model) {
178 // Called when a child is added to children list.
180 // Called when a child is added to children list.
179 var view = this.create_child_view(model);
180 var index = this.containers.length;
181 var index = this.containers.length;
181 var uuid = utils.uuid();
182 var uuid = utils.uuid();
182
183
@@ -184,33 +185,36 b' define(['
184 var tab = $('<li />')
185 var tab = $('<li />')
185 .css('list-style-type', 'none')
186 .css('list-style-type', 'none')
186 .appendTo(this.$tabs);
187 .appendTo(this.$tabs);
187 view.parent_tab = tab;
188
189 var tab_text = $('<a />')
190 .attr('href', '#' + uuid)
191 .attr('data-toggle', 'tab')
192 .text('Page ' + index)
193 .appendTo(tab)
194 .click(function (e) {
195
188
196 // Calling model.set will trigger all of the other views of the
189 this.create_child_view(model, function(view) {
197 // model to update.
190 view.parent_tab = tab;
198 that.model.set("selected_index", index, {updated_view: this});
191
199 that.touch();
192 var tab_text = $('<a />')
200 that.select_page(index);
193 .attr('href', '#' + uuid)
194 .attr('data-toggle', 'tab')
195 .text('Page ' + index)
196 .appendTo(tab)
197 .click(function (e) {
198
199 // Calling model.set will trigger all of the other views of the
200 // model to update.
201 that.model.set("selected_index", index, {updated_view: that});
202 that.touch();
203 that.select_page(index);
204 });
205 tab.tab_text_index = that.containers.push(tab_text) - 1;
206
207 var contents_div = $('<div />', {id: uuid})
208 .addClass('tab-pane')
209 .addClass('fade')
210 .append(view.$el)
211 .appendTo(that.$tab_contents);
212 view.parent_container = contents_div;
213
214 // Trigger the displayed event of the child view.
215 that.after_displayed(function() {
216 view.trigger('displayed');
201 });
217 });
202 tab.tab_text_index = this.containers.push(tab_text) - 1;
203
204 var contents_div = $('<div />', {id: uuid})
205 .addClass('tab-pane')
206 .addClass('fade')
207 .append(view.$el)
208 .appendTo(this.$tab_contents);
209 view.parent_container = contents_div;
210
211 // Trigger the displayed event of the child view.
212 this.after_displayed(function() {
213 view.trigger('displayed');
214 });
218 });
215 },
219 },
216
220
@@ -100,6 +100,8 b' class Widget(LoggingConfigurable):'
100 #-------------------------------------------------------------------------
100 #-------------------------------------------------------------------------
101 _model_name = Unicode('WidgetModel', help="""Name of the backbone model
101 _model_name = Unicode('WidgetModel', help="""Name of the backbone model
102 registered in the front-end to create and sync this widget with.""")
102 registered in the front-end to create and sync this widget with.""")
103 _view_module = Unicode('', help="""A requirejs module in which to find _view_name.
104 If empty, look in the global registry.""", sync=True)
103 _view_name = Unicode(None, allow_none=True, help="""Default view registered in the front-end
105 _view_name = Unicode(None, allow_none=True, help="""Default view registered in the front-end
104 to use to represent the widget.""", sync=True)
106 to use to represent the widget.""", sync=True)
105 comm = Instance('IPython.kernel.comm.Comm')
107 comm = Instance('IPython.kernel.comm.Comm')
General Comments 0
You need to be logged in to leave comments. Login now