PageRenderTime 23ms CodeModel.GetById 10ms app.highlight 9ms RepoModel.GetById 0ms app.codeStats 0ms

/ext-4.0.7/docs/source/Controller.html

https://bitbucket.org/srogerf/javascript
HTML | 430 lines | 395 code | 35 blank | 0 comment | 0 complexity | a5d6bbfb4420e0cb978a64db8e8e3a88 MD5 | raw file
  1<!DOCTYPE html>
  2<html>
  3<head>
  4  <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
  5  <title>The source code</title>
  6  <link href="../resources/prettify/prettify.css" type="text/css" rel="stylesheet" />
  7  <script type="text/javascript" src="../resources/prettify/prettify.js"></script>
  8  <style type="text/css">
  9    .highlight { display: block; background-color: #ddd; }
 10  </style>
 11  <script type="text/javascript">
 12    function highlight() {
 13      document.getElementById(location.hash.replace(/#/, "")).className = "highlight";
 14    }
 15  </script>
 16</head>
 17<body onload="prettyPrint(); highlight();">
 18  <pre class="prettyprint lang-js"><span id='Ext-app-Controller'>/**
 19</span> * @class Ext.app.Controller
 20 *
 21 * Controllers are the glue that binds an application together. All they really do is listen for events (usually from
 22 * views) and take some action. Here's how we might create a Controller to manage Users:
 23 *
 24 *     Ext.define('MyApp.controller.Users', {
 25 *         extend: 'Ext.app.Controller',
 26 *
 27 *         init: function() {
 28 *             console.log('Initialized Users! This happens before the Application launch function is called');
 29 *         }
 30 *     });
 31 *
 32 * The init function is a special method that is called when your application boots. It is called before the
 33 * {@link Ext.app.Application Application}'s launch function is executed so gives a hook point to run any code before
 34 * your Viewport is created.
 35 *
 36 * The init function is a great place to set up how your controller interacts with the view, and is usually used in
 37 * conjunction with another Controller function - {@link Ext.app.Controller#control control}. The control function
 38 * makes it easy to listen to events on your view classes and take some action with a handler function. Let's update
 39 * our Users controller to tell us when the panel is rendered:
 40 *
 41 *     Ext.define('MyApp.controller.Users', {
 42 *         extend: 'Ext.app.Controller',
 43 *
 44 *         init: function() {
 45 *             this.control({
 46 *                 'viewport &gt; panel': {
 47 *                     render: this.onPanelRendered
 48 *                 }
 49 *             });
 50 *         },
 51 *
 52 *         onPanelRendered: function() {
 53 *             console.log('The panel was rendered');
 54 *         }
 55 *     });
 56 *
 57 * We've updated the init function to use this.control to set up listeners on views in our application. The control
 58 * function uses the new ComponentQuery engine to quickly and easily get references to components on the page. If you
 59 * are not familiar with ComponentQuery yet, be sure to check out the {@link Ext.ComponentQuery documentation}. In brief though,
 60 * it allows us to pass a CSS-like selector that will find every matching component on the page.
 61 *
 62 * In our init function above we supplied 'viewport &gt; panel', which translates to &quot;find me every Panel that is a direct
 63 * child of a Viewport&quot;. We then supplied an object that maps event names (just 'render' in this case) to handler
 64 * functions. The overall effect is that whenever any component that matches our selector fires a 'render' event, our
 65 * onPanelRendered function is called.
 66 *
 67 * &lt;u&gt;Using refs&lt;/u&gt;
 68 *
 69 * One of the most useful parts of Controllers is the new ref system. These use the new {@link Ext.ComponentQuery} to
 70 * make it really easy to get references to Views on your page. Let's look at an example of this now:
 71 *
 72 *     Ext.define('MyApp.controller.Users', {
 73 *         extend: 'Ext.app.Controller',
 74 *
 75 *         refs: [
 76 *             {
 77 *                 ref: 'list',
 78 *                 selector: 'grid'
 79 *             }
 80 *         ],
 81 *
 82 *         init: function() {
 83 *             this.control({
 84 *                 'button': {
 85 *                     click: this.refreshGrid
 86 *                 }
 87 *             });
 88 *         },
 89 *
 90 *         refreshGrid: function() {
 91 *             this.getList().store.load();
 92 *         }
 93 *     });
 94 *
 95 * This example assumes the existence of a {@link Ext.grid.Panel Grid} on the page, which contains a single button to
 96 * refresh the Grid when clicked. In our refs array, we set up a reference to the grid. There are two parts to this -
 97 * the 'selector', which is a {@link Ext.ComponentQuery ComponentQuery} selector which finds any grid on the page and
 98 * assigns it to the reference 'list'.
 99 *
100 * By giving the reference a name, we get a number of things for free. The first is the getList function that we use in
101 * the refreshGrid method above. This is generated automatically by the Controller based on the name of our ref, which
102 * was capitalized and prepended with get to go from 'list' to 'getList'.
103 *
104 * The way this works is that the first time getList is called by your code, the ComponentQuery selector is run and the
105 * first component that matches the selector ('grid' in this case) will be returned. All future calls to getList will
106 * use a cached reference to that grid. Usually it is advised to use a specific ComponentQuery selector that will only
107 * match a single View in your application (in the case above our selector will match any grid on the page).
108 *
109 * Bringing it all together, our init function is called when the application boots, at which time we call this.control
110 * to listen to any click on a {@link Ext.button.Button button} and call our refreshGrid function (again, this will
111 * match any button on the page so we advise a more specific selector than just 'button', but have left it this way for
112 * simplicity). When the button is clicked we use out getList function to refresh the grid.
113 *
114 * You can create any number of refs and control any number of components this way, simply adding more functions to
115 * your Controller as you go. For an example of real-world usage of Controllers see the Feed Viewer example in the
116 * examples/app/feed-viewer folder in the SDK download.
117 *
118 * &lt;u&gt;Generated getter methods&lt;/u&gt;
119 *
120 * Refs aren't the only thing that generate convenient getter methods. Controllers often have to deal with Models and
121 * Stores so the framework offers a couple of easy ways to get access to those too. Let's look at another example:
122 *
123 *     Ext.define('MyApp.controller.Users', {
124 *         extend: 'Ext.app.Controller',
125 *
126 *         models: ['User'],
127 *         stores: ['AllUsers', 'AdminUsers'],
128 *
129 *         init: function() {
130 *             var User = this.getUserModel(),
131 *                 allUsers = this.getAllUsersStore();
132 *
133 *             var ed = new User({name: 'Ed'});
134 *             allUsers.add(ed);
135 *         }
136 *     });
137 *
138 * By specifying Models and Stores that the Controller cares about, it again dynamically loads them from the appropriate
139 * locations (app/model/User.js, app/store/AllUsers.js and app/store/AdminUsers.js in this case) and creates getter
140 * functions for them all. The example above will create a new User model instance and add it to the AllUsers Store.
141 * Of course, you could do anything in this function but in this case we just did something simple to demonstrate the
142 * functionality.
143 *
144 * &lt;u&gt;Further Reading&lt;/u&gt;
145 *
146 * For more information about writing Ext JS 4 applications, please see the
147 * [application architecture guide](#/guide/application_architecture). Also see the {@link Ext.app.Application} documentation.
148 *
149 * @docauthor Ed Spencer
150 */
151Ext.define('Ext.app.Controller', {
152
153    mixins: {
154        observable: 'Ext.util.Observable'
155    },
156
157<span id='Ext-app-Controller-cfg-id'>    /**
158</span>     * @cfg {String} id The id of this controller. You can use this id when dispatching.
159     */
160    
161<span id='Ext-app-Controller-cfg-models'>    /**
162</span>     * @cfg {String[]} models
163     * Array of models to require from AppName.model namespace. For example:
164     * 
165     *     Ext.define(&quot;MyApp.controller.Foo&quot;, {
166     *         extend: &quot;Ext.app.Controller&quot;,
167     *         models: ['User', 'Vehicle']
168     *     });
169     * 
170     * This is equivalent of:
171     * 
172     *     Ext.define(&quot;MyApp.controller.Foo&quot;, {
173     *         extend: &quot;Ext.app.Controller&quot;,
174     *         requires: ['MyApp.model.User', 'MyApp.model.Vehicle']
175     *     });
176     * 
177     */
178
179<span id='Ext-app-Controller-cfg-views'>    /**
180</span>     * @cfg {String[]} views
181     * Array of views to require from AppName.view namespace. For example:
182     * 
183     *     Ext.define(&quot;MyApp.controller.Foo&quot;, {
184     *         extend: &quot;Ext.app.Controller&quot;,
185     *         views: ['List', 'Detail']
186     *     });
187     * 
188     * This is equivalent of:
189     * 
190     *     Ext.define(&quot;MyApp.controller.Foo&quot;, {
191     *         extend: &quot;Ext.app.Controller&quot;,
192     *         requires: ['MyApp.view.List', 'MyApp.view.Detail']
193     *     });
194     * 
195     */
196
197<span id='Ext-app-Controller-cfg-stores'>    /**
198</span>     * @cfg {String[]} stores
199     * Array of stores to require from AppName.store namespace. For example:
200     * 
201     *     Ext.define(&quot;MyApp.controller.Foo&quot;, {
202     *         extend: &quot;Ext.app.Controller&quot;,
203     *         stores: ['Users', 'Vehicles']
204     *     });
205     * 
206     * This is equivalent of:
207     * 
208     *     Ext.define(&quot;MyApp.controller.Foo&quot;, {
209     *         extend: &quot;Ext.app.Controller&quot;,
210     *         requires: ['MyApp.store.Users', 'MyApp.store.Vehicles']
211     *     });
212     * 
213     */
214
215    onClassExtended: function(cls, data) {
216        var className = Ext.getClassName(cls),
217            match = className.match(/^(.*)\.controller\./);
218
219        if (match !== null) {
220            var namespace = Ext.Loader.getPrefix(className) || match[1],
221                onBeforeClassCreated = data.onBeforeClassCreated,
222                requires = [],
223                modules = ['model', 'view', 'store'],
224                prefix;
225
226            data.onBeforeClassCreated = function(cls, data) {
227                var i, ln, module,
228                    items, j, subLn, item;
229
230                for (i = 0,ln = modules.length; i &lt; ln; i++) {
231                    module = modules[i];
232
233                    items = Ext.Array.from(data[module + 's']);
234
235                    for (j = 0,subLn = items.length; j &lt; subLn; j++) {
236                        item = items[j];
237
238                        prefix = Ext.Loader.getPrefix(item);
239
240                        if (prefix === '' || prefix === item) {
241                            requires.push(namespace + '.' + module + '.' + item);
242                        }
243                        else {
244                            requires.push(item);
245                        }
246                    }
247                }
248
249                Ext.require(requires, Ext.Function.pass(onBeforeClassCreated, arguments, this));
250            };
251        }
252    },
253
254<span id='Ext-app-Controller-method-constructor'>    /**
255</span>     * Creates new Controller.
256     * @param {Object} config (optional) Config object.
257     */
258    constructor: function(config) {
259        this.mixins.observable.constructor.call(this, config);
260
261        Ext.apply(this, config || {});
262
263        this.createGetters('model', this.models);
264        this.createGetters('store', this.stores);
265        this.createGetters('view', this.views);
266
267        if (this.refs) {
268            this.ref(this.refs);
269        }
270    },
271
272<span id='Ext-app-Controller-method-init'>    /**
273</span>     * A template method that is called when your application boots. It is called before the
274     * {@link Ext.app.Application Application}'s launch function is executed so gives a hook point to run any code before
275     * your Viewport is created.
276     * 
277     * @param {Ext.app.Application} application
278     * @template
279     */
280    init: function(application) {},
281
282<span id='Ext-app-Controller-method-onLaunch'>    /**
283</span>     * A template method like {@link #init}, but called after the viewport is created.
284     * This is called after the {@link Ext.app.Application#launch launch} method of Application is executed.
285     * 
286     * @param {Ext.app.Application} application
287     * @template
288     */
289    onLaunch: function(application) {},
290
291    createGetters: function(type, refs) {
292        type = Ext.String.capitalize(type);
293        Ext.Array.each(refs, function(ref) {
294            var fn = 'get',
295                parts = ref.split('.');
296
297            // Handle namespaced class names. E.g. feed.Add becomes getFeedAddView etc.
298            Ext.Array.each(parts, function(part) {
299                fn += Ext.String.capitalize(part);
300            });
301            fn += type;
302
303            if (!this[fn]) {
304                this[fn] = Ext.Function.pass(this['get' + type], [ref], this);
305            }
306            // Execute it right away
307            this[fn](ref);
308        },
309        this);
310    },
311
312    ref: function(refs) {
313        var me = this;
314        refs = Ext.Array.from(refs);
315        Ext.Array.each(refs, function(info) {
316            var ref = info.ref,
317                fn = 'get' + Ext.String.capitalize(ref);
318            if (!me[fn]) {
319                me[fn] = Ext.Function.pass(me.getRef, [ref, info], me);
320            }
321        });
322    },
323
324    getRef: function(ref, info, config) {
325        this.refCache = this.refCache || {};
326        info = info || {};
327        config = config || {};
328
329        Ext.apply(info, config);
330
331        if (info.forceCreate) {
332            return Ext.ComponentManager.create(info, 'component');
333        }
334
335        var me = this,
336            selector = info.selector,
337            cached = me.refCache[ref];
338
339        if (!cached) {
340            me.refCache[ref] = cached = Ext.ComponentQuery.query(info.selector)[0];
341            if (!cached &amp;&amp; info.autoCreate) {
342                me.refCache[ref] = cached = Ext.ComponentManager.create(info, 'component');
343            }
344            if (cached) {
345                cached.on('beforedestroy', function() {
346                    me.refCache[ref] = null;
347                });
348            }
349        }
350
351        return cached;
352    },
353
354<span id='Ext-app-Controller-method-control'>    /**
355</span>     * Adds listeners to components selected via {@link Ext.ComponentQuery}. Accepts an
356     * object containing component paths mapped to a hash of listener functions.
357     *
358     * In the following example the `updateUser` function is mapped to to the `click`
359     * event on a button component, which is a child of the `useredit` component.
360     *
361     *     Ext.define('AM.controller.Users', {
362     *         init: function() {
363     *             this.control({
364     *                 'useredit button[action=save]': {
365     *                     click: this.updateUser
366     *                 }
367     *             });
368     *         },
369     *
370     *         updateUser: function(button) {
371     *             console.log('clicked the Save button');
372     *         }
373     *     });
374     *
375     * See {@link Ext.ComponentQuery} for more information on component selectors.
376     *
377     * @param {String/Object} selectors If a String, the second argument is used as the
378     * listeners, otherwise an object of selectors -&gt; listeners is assumed
379     * @param {Object} listeners
380     */
381    control: function(selectors, listeners) {
382        this.application.control(selectors, listeners, this);
383    },
384
385<span id='Ext-app-Controller-method-getController'>    /**
386</span>     * Returns instance of a {@link Ext.app.Controller controller} with the given name.
387     * When controller doesn't exist yet, it's created.
388     * @param {String} name
389     * @return {Ext.app.Controller} a controller instance.
390     */
391    getController: function(name) {
392        return this.application.getController(name);
393    },
394
395<span id='Ext-app-Controller-method-getStore'>    /**
396</span>     * Returns instance of a {@link Ext.data.Store Store} with the given name.
397     * When store doesn't exist yet, it's created.
398     * @param {String} name
399     * @return {Ext.data.Store} a store instance.
400     */
401    getStore: function(name) {
402        return this.application.getStore(name);
403    },
404
405<span id='Ext-app-Controller-method-getModel'>    /**
406</span>     * Returns a {@link Ext.data.Model Model} class with the given name.
407     * A shorthand for using {@link Ext.ModelManager#getModel}.
408     * @param {String} name
409     * @return {Ext.data.Model} a model class.
410     */
411    getModel: function(model) {
412        return this.application.getModel(model);
413    },
414
415<span id='Ext-app-Controller-method-getView'>    /**
416</span>     * Returns a View class with the given name.  To create an instance of the view,
417     * you can use it like it's used by Application to create the Viewport:
418     * 
419     *     this.getView('Viewport').create();
420     * 
421     * @param {String} name
422     * @return {Ext.Base} a view class.
423     */
424    getView: function(view) {
425        return this.application.getView(view);
426    }
427});
428</pre>
429</body>
430</html>