-
-
Notifications
You must be signed in to change notification settings - Fork 4.2k
/
view_child_views_support.js
137 lines (109 loc) · 3.55 KB
/
view_child_views_support.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
/**
@module ember
@submodule ember-views
*/
import Ember from 'ember-metal/core';
import { Mixin } from 'ember-metal/mixin';
import { get } from 'ember-metal/property_get';
import { set } from 'ember-metal/property_set';
import setProperties from 'ember-metal/set_properties';
var EMPTY_ARRAY = [];
var ViewChildViewsSupport = Mixin.create({
/**
Array of child views. You should never edit this array directly.
Instead, use `appendChild` and `removeFromParent`.
@property childViews
@type Array
@default []
@private
*/
childViews: EMPTY_ARRAY,
init() {
this._super(...arguments);
// setup child views. be sure to clone the child views array first
// 2.0TODO: Remove Ember.A() here
this.childViews = Ember.A(this.childViews.slice());
this.ownerView = this.ownerView || this;
},
appendChild(view) {
this.linkChild(view);
this.childViews.push(view);
},
destroyChild(view) {
view.destroy();
},
/**
Removes the child view from the parent view.
@method removeChild
@param {Ember.View} view
@return {Ember.View} receiver
@private
*/
removeChild(view) {
// If we're destroying, the entire subtree will be
// freed, and the DOM will be handled separately,
// so no need to mess with childViews.
if (this.isDestroying) { return; }
// update parent node
this.unlinkChild(view);
// remove view from childViews array.
var childViews = get(this, 'childViews');
var index = childViews.indexOf(view);
if (index !== -1) { childViews.splice(index, 1); }
return this;
},
/**
Instantiates a view to be added to the childViews array during view
initialization. You generally will not call this method directly unless
you are overriding `createChildViews()`. Note that this method will
automatically configure the correct settings on the new view instance to
act as a child of the parent.
@method createChildView
@param {Class|String} viewClass
@param {Object} [attrs] Attributes to add
@return {Ember.View} new instance
@private
*/
createChildView(maybeViewClass, _attrs) {
if (!maybeViewClass) {
throw new TypeError('createChildViews first argument must exist');
}
if (maybeViewClass.isView && maybeViewClass.parentView === this && maybeViewClass.container === this.container) {
return maybeViewClass;
}
var attrs = _attrs || {};
var view;
attrs.renderer = this.renderer;
attrs._viewRegistry = this._viewRegistry;
if (maybeViewClass.isViewFactory) {
attrs.container = this.container;
view = maybeViewClass.create(attrs);
if (view.viewName) {
set(this, view.viewName, view);
}
} else if ('string' === typeof maybeViewClass) {
var fullName = 'view:' + maybeViewClass;
var ViewKlass = this.container.lookupFactory(fullName);
Ember.assert('Could not find view: \'' + fullName + '\'', !!ViewKlass);
view = ViewKlass.create(attrs);
} else {
view = maybeViewClass;
Ember.assert('You must pass instance or subclass of View', view.isView);
attrs.container = this.container;
setProperties(view, attrs);
}
this.linkChild(view);
return view;
},
linkChild(instance) {
instance.container = this.container;
set(instance, 'parentView', this);
instance.trigger('parentViewDidChange');
instance.ownerView = this.ownerView;
},
unlinkChild(instance) {
set(instance, 'parentView', null);
instance.trigger('parentViewDidChange');
}
});
export default ViewChildViewsSupport;