Introducing React ReExt – Sencha Ext JS Components in React! LEARN MORE

ExtJS Component listeners: Sprinkling the syntactical sugar

July 24, 2019 109 Views
Show

ExtJS 6.5.1 saw an update to the way in which Ext.callback resolved scope. It was a welcome change that added new and exciting possibilities to the way in which callbacks could be constructed and configured. The main change was the introduction of ‘callback syntax’ and by callback syntax I mean the ability to pass instruction to the callback mechanism as to the path to take to perform scope resolution.

Prior to the changes made in ExtJS 6.5.1, scope resolution was limited to either providing scope directly to the callback or specifying scope to be one of the standard sets of ‘named scopes’

Ext._namedScopes: {
	controller: {isController: 1}
	owner: {isOwner: 1}
	self: {isSelf: 1}
	self.controller: {isSelf: 1, isController: 1}
	this: {isThis: 1}
}

Now these are all well and good, but the problem with this is that you do not always have access to the object scope that you wish to define for your callback, or perhaps your complex application architecture makes named scope resolution a little tricky in some cases. There is also the case for those that like to keep their classes as declarative as possible where this often means having to wrap a perfectly good piece of config in a function call just to gain access to the required object scope for a listener or callback. Or perhaps, if you are using MVVM, writing a controller to push the logic into when you had preferred to keep it contained within your original component class. Sometimes this could also add additional challenges with which to provide a clean way to override behaviour when working with components, classes and in particular shared/global controllers.

To the rescue comes the new callback syntactical sugar sprinkled over ExtJS 6.5.1, which provides a way in which to search for the desired scope using the component hierarchy. The new syntax takes the form of ‘up.’ So for example, when

Ext.callback('up.onFoo',..., button)

is called, a search is then performed using the standard component method ‘up’

"button.up('[onFoo]')"

in order to search for the handler. Thus we have a declarative way to dispatch such handlers that will work even if you cannot easily supply such handlers. In addition we now also have a convenient way with which to override component behaviour leveraging the new callback syntax as you are able to place your override at ANY point between the object initiating the callback and the base method that would otherwise get called.

Unfortunately the new callback syntax has only been added to Ext.callback and so it is currently not possible to take advantage of this when declaring listeners, it only works for components which have ‘handlers’ or when calling Ext.callback directly.

Common ways in which you can define scope and/or method resolution on a listener config are:
Anonymous function – Here you are providing the method and its scope (anonymous) to the listener config directly, there is nothing to get resolved here. This can be a bit clunky and is usually only appropriate for cases where you have a very small bit of logic to apply and where creating a controller to place the method might be overkill. Having lots of anonymous functions defined for your listeners will not make your code particularly easy to read or maintain.


	{
		xtype: ‘someclass’,
		listeners: {
			change: function(comp, newVal, oldVal) {
				// do something
			}
		}
	}

Defined function on scoped object – Here you are providing the scoped object and the method. The framework does not have much work to do here as you are providing both the scope and the function in the config. However, the drawback with this approach is that it has to be wrapped by another function with which the scope object ‘scopedObject’ gets defined. – Which can sometimes end up cluttering up your lovely declarative class definition.


	{
		xtype: ‘someclass’,
		listeners: {
			change: scopedObject.someFunction
		}
	}

Declarative function – Here you are providing the method but not its scope. The framework will attempt to resolve the scope for you by looking in appropriate objects, be they other components or controllers.


	{
		xtype: ‘someclass’,
		listeners: {
			change: ‘someFunction’
		}
	}

Declarative function with concrete scope – This is basically the same as having a defined function on a scoped object except that you are splitting apart the method name and the scope object providing the method name in a declarative form and with the same scope object also applying to all of your listener configuration.


	{
		xtype: ‘someclass’,
		listeners: {
			change: ‘someFunction’,
			scope: me
		}
	}

Declarative function with named scope – Here you are providing the method name in a declarative form and in addition you are also providing the scope object name where the framework can locate the method. When constructing the listener the framework will attempt the resolve the listener scope provided as a name such as ‘this’ or ‘self’ or ‘controller’ for example.

	{
		xtype: ‘someclass’,
		listeners: {
			change: ‘someFunction’,
			scope: ‘controller’
		}
	}

Although listeners have their own methods for scope resolution, the same functionality of traversing up through the component hierarchy to find the desired scope would be a nice addition to the developer’s toolbox and perhaps Sencha will look to add this syntactic sugar to listener definition in the near future?

To demonstrate how one ‘could’ apply the same kind of syntactical sugar to the ‘listeners’ config of a component I have created a fiddle with a few key overrides. https://fiddle.sencha.com/#view/editor&fiddle/2tcl

Please check it out. I would be interested to hear if you think this would be a useful addition to the framework.

As somebody who loves to write declaratively, I’d also be interested to know if there are any other places within the framework where you think that syntactical sugar could be applied to make your life easier and your code easier to read and maintain?

Show
Start building with Ext JS today

Build 10x web apps faster with 140+ pre-build components and tools.

Latest Content
Discover the Top 07 Architecture Patterns used in Modern Enterprise Software Development
Discover the Top 07 Architecture Patterns used in Modern Enterprise Software Development

Developing software without an architecture pattern may have been an option back then. However, that’s…

JavaScript Design Patterns: A Hands-On Guide with Real-world Examples
JavaScript Design Patterns: A Hands-On Guide with Real-world Examples

As a web developer, you know how popular JavaScript is in the web app development…

Virtual JS Days 2024のハイライト
Virtual JS Days 2024のハイライト

2024年2月20日~22日、第3回目となる「Virtual JavaScript Days」が開催されました。JavaScript の幅広いトピックを採り上げた数多くのセッションを実施。その内容は、Senchaの最新製品、ReExt、Rapid Ext JSまで多岐にわたり、JavaScriptの最新のサンプルも含まれます。 このカンファレンスでは多くのトピックをカバーしています。Senchaでセールスエンジニアを務めるMarc Gusmano氏は、注目すべきセッションを主催しました。Marc は Sencha の最新製品「ReExt」について、詳細なプレゼンテーションを実施。その機能とメリットを、参加者に理解してもらうべく詳細に説明しました。 カンファレンスは、Senchaのジェネラルマネージャを務めるStephen Strake氏によるキーノートでスタートしました。キーノートでは、会社の将来のビジョンについての洞察を共有しています。世界中から JavaScript 開発者、エンジニア、愛好家が集まるとてもエキサイティングなイベントとなりました。これは、JavaScript…

See More