Ext.app.Controller
. These controllers use CSS-like selectors (called "Component Queries") to map components and event handlers for their events. They also use the so-called refs
for sampling and obtaining instances of components.Ext.app.ViewController
. The solution is achieved as follows:listeners
and reference
, communication with views is simplified.listeners
not new, but in Ext JS 5 it acquired new features. A more complete analysis of new listeners will be in the upcoming article - “Declarative Listeners in Ext JS 5”. For use in ViewControllers, we can look at a couple of examples. The first is the usual use of the listeners
in the nested view component: Ext.define('MyApp.view.foo.Foo', { extend: 'Ext.panel.Panel', xtype: 'foo', controller: 'foo', items: [{ xtype: 'textfield', fieldLabel: 'Bar', listeners: { change: 'onBarChange' // (scope) } }] }); Ext.define('MyApp.view.foo.FooController', { extend: 'Ext.app.ViewController', alias: 'controller.foo', onBarChange: function (barTextField) { // 'change' } });
onBarChange
handler onBarChange
not have a specific context ( scope
). The event system for the Bar
text field independently makes the default context its own ViewController.listeners
config has been reserved for use by the parent component, so the question arises: how can the presentation listen to its own events or perhaps even those that were caused by the base class? The answer is to use an explicit context: Ext.define('MyApp.view.foo.Foo', { extend: 'Ext.panel.Panel', xtype: 'foo', controller: 'foo', listeners: { collapse: 'onCollapse', scope: 'controller' }, items: [{ ... }] });
"this"
and "controller"
. When we write MVC applications, we almost always use a "controller"
, which obviously will be its own ViewController (and not a ViewController of a view that is higher in the hierarchy).Ext.Component
, we have assigned the xtype
this view, which allows other views to create an instance of it just as we did with the textfield
. To see how everything fits together, create a hierarchy: Ext.define('MyApp.view.bar.Bar', { extend: 'Ext.panel.Panel', xtype: 'bar', controller: 'bar', items: [{ xtype: 'foo', listeners: { collapse: 'onCollapse' } }] });
Bar
view creates an instance of Foo
as one of its elements. Then it listens to the collapse
event, just like the Foo
view. In previous versions of Ext JS and Sencha Touch, these definitions would conflict. However, in Ext JS 5 this is solved: the listeners declared in Foo
will work in ViewController'e Foo
, and those declared in Bar
- in ViewController'e Bar
. Ext.define('MyApp.view.foo.Foo', { extend: 'Ext.panel.Panel', xtype: 'foo', controller: 'foo', tbar: [{ xtype: 'button', text: 'Add', handler: 'onAdd' }], items: [{ xtype: 'grid', ... }] }); Ext.define('MyApp.view.foo.FooController', { extend: 'Ext.app.ViewController', alias: 'controller.foo', onAdd: function () { // ... grid ... } });
refs
or some other way to get the component. All technicians require you to give a recognizable property to a table in order to uniquely identify it. Older technicians used the id
(and Ext.getCmp
) Ext.getCmp
or itemId
(using refs
or another selection method). The advantage of id
is quick sampling, but because identifiers must be unique in the entire application and in the DOM, this is not always achievable. Using itemId
and different types of queries (query) is more flexible, but you need to perform a search to find the desired component.reference
config in Ext JS 5, we simply add it to the table and use the lookupReference
to get it: Ext.define('MyApp.view.foo.Foo', { extend: 'Ext.panel.Panel', xtype: 'foo', controller: 'foo', tbar: [{ xtype: 'button', text: 'Add', handler: 'onAdd' }], items: [{ xtype: 'grid', reference: 'fooGrid' ... }] }); Ext.define('MyApp.view.foo.FooController', { extend: 'Ext.app.ViewController', alias: 'controller.foo', onAdd: function () { var grid = this.lookupReference('fooGrid'); } });
itemId = 'fooGrid'
and further this.down('#fooGrid')
. But "under the hood" the difference is significant. First, the reference
config requires the component to register itself with the owner-view. Secondly, the lookupReference
method asks the cache about the need to update (suppose, due to the addition or removal in the container). If everything is fine, it simply returns the link from the cache. In pseudocode: lookupReference: (reference) { var cache = this.references; if (!cache) { Ext.fixReferences(); // cache = this.references; // } return cache[reference]; }
reference
and listeners
configs connect the view only with its ViewController. Nested views can use any reference
values ​​within the current one, knowing that these names will not be open to the view that is higher in the hierarchy.listeners
requested from the corresponding ViewController and cannot be processed in other controllers with incorrect selectors. Considering that listeners are more preferable than selectors, these two mechanisms can work simultaneously in those places when the use of a selector-based approach is justified.fireViewEvent
: fireViewEvent
. For example: Ext.define('MyApp.view.foo.Foo', { extend: 'Ext.panel.Panel', xtype: 'foo', controller: 'foo', tbar: [{ xtype: 'button', text: 'Add', handler: 'onAdd' }], items: [{ xtype: 'grid', reference: 'fooGrid' ... }] }); Ext.define('MyApp.view.foo.FooController', { extend: 'Ext.app.ViewController', alias: 'controller.foo', onAdd: function () { var record = new MyApp.model.Thing(); var grid = this.lookupReference('fooGrid'); grid.store.add(record); this.fireViewEvent('addrecord', this, record); } });
Ext.define('MyApp.view.bar.Bar', { extend: 'Ext.panel.Panel', xtype: 'bar', controller: 'bar', items: [{ xtype: 'foo', listeners: { collapse: 'onCollapse', addrecord: 'onAddRecord' } }] });
fireViewEvent
allows fireViewEvent
to raise an event for a view inside a ViewController. That is, if in this case there were no ViewControllers, it would be equivalent to calling the usual fireEvent
in the “Foo” view code.component
has full support for component selectors, while others are limited.view
. This event domain allows ViewControllers to use standard methods of listen
and control
, while implicitly limiting their scope to their own views. He also adds a new special selector to match his own view: Ext.define('MyApp.view.foo.FooController', { extend: 'Ext.app.ViewController', alias: 'controller.foo', control: { '#': { // collapse: 'onCollapse' }, button: { click: 'onAnyButtonClick' } } });
button
coincides with any button in this view or in any nested, it does not matter, even in the sub-sub-nested. In other words, handlers based on selectors do not consider inheritance boundaries. This behavior is the same as the previous Ext.app.Controller
behavior and in some situations it can be a useful technique.component
for processing in Ext.app.Controller
controllers.initConfig
or its constructor is initConfig
.initComponent
method has completed in the initComponent
. This is a typical time to perform controller initialization, the view of which has already been initialized.callParent
).Source: https://habr.com/ru/post/224645/
All Articles