]> git.proxmox.com Git - extjs.git/blame - extjs/packages/core/src/mixin/Container.js
add extjs 6.0.1 sources
[extjs.git] / extjs / packages / core / src / mixin / Container.js
CommitLineData
6527f429
DM
1/**\r
2 * @private\r
3 * Common methods for both classic & modern containers\r
4 */\r
5Ext.define('Ext.mixin.Container', {\r
6 extend: 'Ext.Mixin',\r
7\r
8 mixinConfig: {\r
9 id: 'container'\r
10 },\r
11\r
12 /**\r
13 * @property {Boolean} isContainer\r
14 * `true` in this class to identify an object as an instantiated Container, or subclass thereof.\r
15 */\r
16 isContainer: true,\r
17\r
18 config: {\r
19 /**\r
20 * @cfg {Boolean} referenceHolder\r
21 * If `true`, this container will be marked as being a point in the hierarchy where\r
22 * references to items with a specified `reference` config will be held. The container\r
23 * will automatically become a referenceHolder if a {@link #controller} is specified.\r
24 *\r
25 * See the introductory docs for {@link Ext.container.Container} for more information\r
26 * about references & reference holders.\r
27 */\r
28 referenceHolder: false\r
29 },\r
30\r
31 /**\r
32 * Returns an object holding the descendants of this view keyed by their\r
33 * `{@link Ext.Component#cfg-reference reference}`. This object should not be held\r
34 * past the scope of the function calling this method. It will not be valid if items\r
35 * are added or removed from this or any sub-container.\r
36 *\r
37 * The intended usage is shown here (assume there are 3 components with reference\r
38 * values of "foo", "bar" and "baz" at some level below this container):\r
39 *\r
40 * onClick: function () {\r
41 * var refs = this.getReferences();\r
42 *\r
43 * // using "refs" we can access any descendant by its "reference"\r
44 *\r
45 * refs.foo.getValue() + refs.bar.getValue() + refs.baz.getValue();\r
46 * }\r
47 *\r
48 * If `this` component has a `{@link Ext.Component#cfg-reference reference}` assigned\r
49 * to it, that is **not** included in this object. That reference is understood to\r
50 * belong to the ancestor container configured as the `referenceHolder`.\r
51 *\r
52 * @return {Object} An object with each child reference. This will be `null` if this\r
53 * container has no descendants with a `{@link Ext.Component#cfg-reference reference}`\r
54 * specified.\r
55 * @since 5.0.0\r
56 */\r
57 getReferences: function () {\r
58 Ext.ComponentManager.fixReferences();\r
59 return this.refs || null;\r
60 },\r
61\r
62 /**\r
63 * Gets a reference to the component with the specified {@link #reference} value.\r
64 *\r
65 * The method is a short-hand for the {@link #lookupReference} method.\r
66 *\r
67 * @param {String} key The name of the reference to lookup.\r
68 * @return {Ext.Component} The referenced component or `null` if it is not found.\r
69 * @since 6.0.1\r
70 */\r
71 lookup: function (key) {\r
72 var refs = this.getReferences();\r
73 return (refs && refs[key]) || null;\r
74 },\r
75\r
76 /**\r
77 * Gets a reference to the component with the specified {@link #reference} value.\r
78 *\r
79 * The {@link #lookup} method is a short-hand version of this method.\r
80 *\r
81 * @param {String} key The name of the reference to lookup.\r
82 * @return {Ext.Component} The referenced component or `null` if it is not found.\r
83 * @since 5.0\r
84 */\r
85 lookupReference: function (key) {\r
86 return this.lookup(key);\r
87 },\r
88\r
89 privates: {\r
90 /**\r
91 * Sets up a component reference.\r
92 * @param {Ext.Component} component The component to reference.\r
93 * @private\r
94 */\r
95 attachReference: function (component) {\r
96 var me = this,\r
97 key, refs;\r
98\r
99 // Cleaning all this up later anyway\r
100 if (me.destroying || me.destroyed) {\r
101 return;\r
102 }\r
103\r
104 refs = me.refs || (me.refs = {});\r
105 key = component.referenceKey;\r
106 //<debug>\r
107 if (refs[key] && refs[key] !== component) {\r
108 Ext.log.warn('Duplicate reference: "' + key + '" on ' + me.id);\r
109 }\r
110 //</debug>\r
111 refs[key] = component;\r
112 },\r
113\r
114 /**\r
115 * Clear a component reference.\r
116 * @param {Ext.Component} component The component to remove.\r
117 * @private\r
118 */\r
119 clearReference: function (component) {\r
120 var refs = this.refs,\r
121 key = component.referenceKey;\r
122\r
123 if (refs && key) {\r
124 // viewModelKey would be better placed in app.Container however\r
125 // it's not really worth introducing a second method call to clear\r
126 // a single property.\r
127 component.viewModelKey = component.referenceKey = refs[key] = null;\r
128 }\r
129 },\r
130\r
131 containerOnAdded: function(component, instanced) {\r
132 // We have been added to a container, we may have child references\r
133 // or be a reference ourself. At this point we have no way of knowing if \r
134 // our references are correct, so trigger a fix.\r
135 if (instanced) {\r
136 Ext.ComponentManager.markReferencesDirty();\r
137 }\r
138 },\r
139\r
140 containerOnRemoved: function(destroying) {\r
141 var refHolder;\r
142 \r
143 // If we're destroying this will get cleaned up anyway\r
144 if (!destroying) {\r
145 refHolder = this.lookupReferenceHolder();\r
146 if (refHolder) {\r
147 // Clear any references here, they will be reset after the \r
148 // next call to lookupReference after being marked dirty.\r
149 // It's easier to wipe & re-establish them than attempt to \r
150 // track what changed and prune the collection\r
151 \r
152 Ext.ComponentManager.markReferencesDirty();\r
153 refHolder.clearReferences();\r
154 }\r
155 }\r
156 }, \r
157\r
158 /**\r
159 * Invalidates the references collection. Typically called when\r
160 * removing a container from this container, since it's difficult\r
161 * to know what references got removed.\r
162 *\r
163 * @private\r
164 */\r
165 clearReferences: function () {\r
166 this.refs = null;\r
167 },\r
168\r
169 initContainerInheritedState: function(inheritedState, inheritedStateInner) {\r
170 var me = this,\r
171 controller = me.getController(),\r
172 session = me.getSession(),\r
173 // Don't instantiate it here, we just want to know whether we\r
174 // were configured with a VM\r
175 viewModel = me.getConfig('viewModel', true),\r
176 reference = me.getReference(),\r
177 referenceHolder = me.getReferenceHolder();\r
178\r
179\r
180\r
181 if (controller) {\r
182 inheritedState.referenceHolder = controller;\r
183 referenceHolder = true;\r
184 } else if (referenceHolder) {\r
185 inheritedState.referenceHolder = me;\r
186 }\r
187\r
188 if (referenceHolder) {\r
189 inheritedState.referencePath = '';\r
190 } else if (reference && me.isParentReference) {\r
191 inheritedState.referencePath = me.referenceKey + '.';\r
192 }\r
193\r
194 if (session) {\r
195 inheritedState.session = session;\r
196 }\r
197\r
198 if (viewModel) {\r
199 inheritedState.viewModelPath = '';\r
200 } else if (reference && me.isParentReference) {\r
201 inheritedState.viewModelPath = me.viewModelKey + '.';\r
202 }\r
203 },\r
204 \r
205 setupReference: function(reference) {\r
206 var len;\r
207\r
208 if (reference && reference.charAt(len = reference.length - 1) === '>') {\r
209 this.isParentReference = true;\r
210 reference = reference.substring(0, len);\r
211 }\r
212\r
213 //<debug>\r
214 if (reference && !Ext.validIdRe.test(reference)) {\r
215 Ext.Error.raise('Invalid reference "' + reference + '" for ' + this.getId() +\r
216 ' - not a valid identifier');\r
217 }\r
218 //</debug>\r
219\r
220 return reference;\r
221 }\r
222 }\r
223});