Show More
@@ -325,6 +325,7 b' define(["widgets/js/manager",' | |||||
325 |
|
325 | |||
326 | pop_child_view: function(child_model) { |
|
326 | pop_child_view: function(child_model) { | |
327 | // Delete a child view that was previously created using create_child_view. |
|
327 | // Delete a child view that was previously created using create_child_view. | |
|
328 | console.error("Deprecated use of WidgetView.pop_child_view; use a ViewList instead"); | |||
328 | var view_ids = this.child_model_views[child_model.id]; |
|
329 | var view_ids = this.child_model_views[child_model.id]; | |
329 | if (view_ids !== undefined) { |
|
330 | if (view_ids !== undefined) { | |
330 |
|
331 | |||
@@ -358,6 +359,8 b' define(["widgets/js/manager",' | |||||
358 | // Callback that is called for each item added. |
|
359 | // Callback that is called for each item added. | |
359 |
|
360 | |||
360 | // Walk the lists until an unequal entry is found. |
|
361 | // Walk the lists until an unequal entry is found. | |
|
362 | console.error("Deprecated _do_diff; use a ViewList or related class instead"); | |||
|
363 | ||||
361 | var i; |
|
364 | var i; | |
362 | for (i = 0; i < new_list.length; i++) { |
|
365 | for (i = 0; i < new_list.length; i++) { | |
363 | if (i >= old_list.length || new_list[i] !== old_list[i]) { |
|
366 | if (i >= old_list.length || new_list[i] !== old_list[i]) { | |
@@ -588,11 +591,87 b' define(["widgets/js/manager",' | |||||
588 | }, |
|
591 | }, | |
589 | }); |
|
592 | }); | |
590 |
|
593 | |||
591 |
|
594 | |||
|
595 | var ViewList = function(create_view, remove_view, context) { | |||
|
596 | // * create_view and remove_view are default functions called when adding or removing views | |||
|
597 | // * create_view takes a model and creates a view or a promise for a view for that model | |||
|
598 | // * remove_view takes a view and destroys it (including calling `.remove()`) | |||
|
599 | // * each time the update() function is called with a new list, the create and destroy | |||
|
600 | // callbacks will be called in an order so that if you append the views created in the | |||
|
601 | // create callback, you will duplicate the order of the list. | |||
|
602 | // * the remove callback defaults to just removing the view (if you pass in null) | |||
|
603 | // * the context defaults to the ViewList. If you pass another context, the create and remove | |||
|
604 | // will be called in that context. | |||
|
605 | ||||
|
606 | this.initialize.apply(this, arguments); | |||
|
607 | this.state_change = Promise.resolve(); | |||
|
608 | } | |||
|
609 | ||||
|
610 | _.extend(ViewList.prototype, { | |||
|
611 | initialize: function(create_view, remove_view, context) { | |||
|
612 | this._handler_context = context || this; | |||
|
613 | this._models = []; | |||
|
614 | this.views = []; | |||
|
615 | this._create_view = create_view; | |||
|
616 | this._remove_view = remove_view || function(view) {view.remove()}; | |||
|
617 | }, | |||
|
618 | ||||
|
619 | update: function(new_models, create_view, remove_view, context) { | |||
|
620 | // the create_view, remove_view, and context arguments override the defaults | |||
|
621 | // specified when the list is created. | |||
|
622 | // returns a promise that resolves after this update is done | |||
|
623 | var remove = remove_view || this._remove_view; | |||
|
624 | var create = create_view || this._create_view; | |||
|
625 | var context = context || this._handler_context; | |||
|
626 | var added_views = []; | |||
|
627 | var that = this; | |||
|
628 | this.state_change = this.state_change.then(function() { | |||
|
629 | var i; | |||
|
630 | // first, skip past the beginning of the lists if they are identical | |||
|
631 | for (i = 0; i < new_models.length; i++) { | |||
|
632 | if (i >= that._models.length || new_models[i] !== that._models[i]) { | |||
|
633 | break; | |||
|
634 | } | |||
|
635 | } | |||
|
636 | var first_removed = i; | |||
|
637 | // Remove the non-matching items from the old list. | |||
|
638 | for (var j = first_removed; j < that._models.length; j++) { | |||
|
639 | remove.call(context, that.views[j]); | |||
|
640 | } | |||
|
641 | ||||
|
642 | // Add the rest of the new list items. | |||
|
643 | for (; i < new_models.length; i++) { | |||
|
644 | added_views.push(create.call(context, new_models[i])); | |||
|
645 | } | |||
|
646 | that._models = new_models; | |||
|
647 | return Promise.all(added_views, function(added) { | |||
|
648 | that.views = that.views.slice(0,first_removed).concat(added); | |||
|
649 | }); | |||
|
650 | }); | |||
|
651 | return this.state_change; | |||
|
652 | }, | |||
|
653 | ||||
|
654 | remove: function() { | |||
|
655 | // removes every view in our list; convenience function for `.update([])` | |||
|
656 | // that should be faster | |||
|
657 | // returns a promise that resolves after this removal is done | |||
|
658 | var that = this; | |||
|
659 | this.state_change = this.state_change.then(function() { | |||
|
660 | for (var i = 0, len=that.views.length; i <len; i++) { | |||
|
661 | that._remove_view.call(that._handler_context, that.views[i]); | |||
|
662 | }; | |||
|
663 | that._models = []; | |||
|
664 | that.views = []; | |||
|
665 | }); | |||
|
666 | return this.state_change; | |||
|
667 | }, | |||
|
668 | }); | |||
|
669 | ||||
592 | var widget = { |
|
670 | var widget = { | |
593 | 'WidgetModel': WidgetModel, |
|
671 | 'WidgetModel': WidgetModel, | |
594 | 'WidgetView': WidgetView, |
|
672 | 'WidgetView': WidgetView, | |
595 | 'DOMWidgetView': DOMWidgetView, |
|
673 | 'DOMWidgetView': DOMWidgetView, | |
|
674 | 'ViewList': ViewList, | |||
596 | }; |
|
675 | }; | |
597 |
|
676 | |||
598 | // For backwards compatability. |
|
677 | // For backwards compatability. |
@@ -12,16 +12,17 b' define([' | |||||
12 | initialize: function(){ |
|
12 | initialize: function(){ | |
13 | // Public constructor |
|
13 | // Public constructor | |
14 | BoxView.__super__.initialize.apply(this, arguments); |
|
14 | BoxView.__super__.initialize.apply(this, arguments); | |
15 | this.model.on('change:children', function(model, value) { |
|
15 | this.children_views = new widget.ViewList(this.add_child_model, null, this); | |
16 | this.update_children(model.previous('children'), value); |
|
16 | this.listenTo(this.model, 'change:children', function(model, value) { | |
|
17 | this.children_views.update(value); | |||
17 | }, this); |
|
18 | }, this); | |
18 |
this.model |
|
19 | this.listenTo(this.model, 'change:overflow_x', function(model, value) { | |
19 | this.update_overflow_x(); |
|
20 | this.update_overflow_x(); | |
20 | }, this); |
|
21 | }, this); | |
21 |
this.model |
|
22 | this.listenTo(this.model, 'change:overflow_y', function(model, value) { | |
22 | this.update_overflow_y(); |
|
23 | this.update_overflow_y(); | |
23 | }, this); |
|
24 | }, this); | |
24 |
this.model |
|
25 | this.listenTo(this.model, 'change:box_style', function(model, value) { | |
25 | this.update_box_style(); |
|
26 | this.update_box_style(); | |
26 | }, this); |
|
27 | }, this); | |
27 | }, |
|
28 | }, | |
@@ -35,7 +36,7 b' define([' | |||||
35 | // Called when view is rendered. |
|
36 | // Called when view is rendered. | |
36 | this.$box = this.$el; |
|
37 | this.$box = this.$el; | |
37 | this.$box.addClass('widget-box'); |
|
38 | this.$box.addClass('widget-box'); | |
38 |
this. |
|
39 | this.children_views.update(this.model.get('children')); | |
39 | this.update_overflow_x(); |
|
40 | this.update_overflow_x(); | |
40 | this.update_overflow_y(); |
|
41 | this.update_overflow_y(); | |
41 | this.update_box_style(''); |
|
42 | this.update_box_style(''); | |
@@ -61,18 +62,6 b' define([' | |||||
61 | this.update_mapped_classes(class_map, 'box_style', previous_trait_value, this.$box); |
|
62 | this.update_mapped_classes(class_map, 'box_style', previous_trait_value, this.$box); | |
62 | }, |
|
63 | }, | |
63 |
|
64 | |||
64 | update_children: function(old_list, new_list) { |
|
|||
65 | // Called when the children list changes. |
|
|||
66 | this.do_diff(old_list, new_list, |
|
|||
67 | $.proxy(this.remove_child_model, this), |
|
|||
68 | $.proxy(this.add_child_model, this)); |
|
|||
69 | }, |
|
|||
70 |
|
||||
71 | remove_child_model: function(model) { |
|
|||
72 | // Called when a model is removed from the children list. |
|
|||
73 | this.pop_child_view(model).remove(); |
|
|||
74 | }, |
|
|||
75 |
|
||||
76 | add_child_model: function(model) { |
|
65 | add_child_model: function(model) { | |
77 | // Called when a model is added to the children list. |
|
66 | // Called when a model is added to the children list. | |
78 | var that = this; |
|
67 | var that = this; | |
@@ -88,16 +77,21 b' define([' | |||||
88 | return view; |
|
77 | return view; | |
89 | }, utils.reject("Couldn't add child view to box", true)); |
|
78 | }, utils.reject("Couldn't add child view to box", true)); | |
90 | }, |
|
79 | }, | |
|
80 | ||||
|
81 | remove: function() { | |||
|
82 | BoxView.__super__.remove.apply(this, arguments); | |||
|
83 | this.children_views.remove(); | |||
|
84 | }, | |||
91 | }); |
|
85 | }); | |
92 |
|
86 | |||
93 |
|
87 | |||
94 | var FlexBoxView = BoxView.extend({ |
|
88 | var FlexBoxView = BoxView.extend({ | |
95 | render: function(){ |
|
89 | render: function(){ | |
96 | FlexBoxView.__super__.render.apply(this); |
|
90 | FlexBoxView.__super__.render.apply(this); | |
97 |
this.model |
|
91 | this.listenTo(this.model, 'change:orientation', this.update_orientation, this); | |
98 |
this.model |
|
92 | this.listenTo(this.model, 'change:flex', this._flex_changed, this); | |
99 |
this.model |
|
93 | this.listenTo(this.model, 'change:pack', this._pack_changed, this); | |
100 |
this.model |
|
94 | this.listenTo(this.model, 'change:align', this._align_changed, this); | |
101 | this._flex_changed(); |
|
95 | this._flex_changed(); | |
102 | this._pack_changed(); |
|
96 | this._pack_changed(); | |
103 | this._align_changed(); |
|
97 | this._align_changed(); | |
@@ -244,10 +238,7 b' define([' | |||||
244 | this._shown_once = false; |
|
238 | this._shown_once = false; | |
245 | this.popped_out = true; |
|
239 | this.popped_out = true; | |
246 |
|
240 | |||
247 |
this. |
|
241 | this.children_views.update(this.model.get('children')) | |
248 | this.model.on('change:children', function(model, value) { |
|
|||
249 | this.update_children(model.previous('children'), value); |
|
|||
250 | }, this); |
|
|||
251 | }, |
|
242 | }, | |
252 |
|
243 | |||
253 | hide: function() { |
|
244 | hide: function() { |
General Comments 0
You need to be logged in to leave comments.
Login now