Today we’re excited to release the first in a series of brand new features in Ext JS 4. Over the next few weeks we’ll be rolling out our beta release of Ext JS — package by package. Although we originally planned to release a full beta about now, some parts of the framework have been stabilizing more slowly than expected, so we’re going to roll out the packages incrementally instead. Today, we’re starting with the brand new Ext JS 4 class system.
今天,我们很高兴在这里第一次发布Ext 4的一系列新特性。在接下来的几个星期里,我们将推出由包封装的Ext JS 4 Beta版本。虽然我们原计划是在现在发布一个完整的测试版本,但一部分框架进度比预期慢,因此我们不得不逐步发布,而不是通过单一包发布。今天,我们将开始使用全新的Ext JS 4类系统。
JavaScript has no Classes of its own, which can make it an unfamiliar environment for newcomers to the language. Ext JS has always provided a class system of its own which utilizes the language’s powerful prototype pattern while enabling developers to write code with a more traditional Object Oriented approach.
JavaScript没有自己的类系统,因而对新开发者来说是一个陌生的语言环境。 Ext JS一直通过JavaScript强大的原型模型为开发者提供它自己的类系统,,从而让开发者可以编写一个更传统的面向对象的代码。
With Ext JS 4, we’re taking the class system to the next level with a series of new features to make your development easier and more flexible. Ext 4 will introduce four new features – class definitions, mixins, setters and getters for configurations, and dependency loading.
在Ext JS 4中,我们提供一个全新特性的类系统,从而让开发更简单,更灵活。Ext 4将推出4个新特性:类定义、mixins、输入和输出配置及依赖加载。
上图重点介绍我们新的类系统的好处,最引人注目的是Draggable和Resizable将成为mixin。
类定义
To compare, let’s take a look at how we used to create a new class in Ext JS 3. In this example, we create a fictional login window class that extends Ext.Window:
我们来比较一下在Ext JS 3和Ext JS4中是如何创建一个新类的。在例子中,我们将创建一个扩展自Ext.Window的登录窗口类:
1 | // Ext JS 3.x class definition |
2 | MyApp . LoginWindow = Ext . extend ( Ext . Window , { |
3 | title : ' Log in ' , |
4 | |
5 | initComponent : function ( ) { |
6 | Ext . apply ( this , { |
7 | items : [ |
8 | { |
9 | xtype : ' textfield ' , |
10 | name : ' username ' , |
11 | fieldLabel : ' Username ' |
12 | } , |
13 | . . . |
14 | ] |
15 | } ) ; |
16 | |
17 | MyApp . LoginWindow . superclass . initComponent . apply ( this , arguments ) ; |
18 | } |
19 | } ) ; |
This is probably familiar to most of you and it works well, though it does have some pitfalls. If Ext.Window were not defined when we create our class, we would get an error and our application might crash. Similarly, if the MyApp namespace is not defined we’d also get an error. These problems are both resolved with the new way to define classes:
尽管有一些缺陷,但这可能是你很熟悉的,而且效果最好的在Ext JS 3中的类定义方式。如果Ext.Widow没有定义,那么当我们创建我们自己的类的时候,我们将会得到一个错误甚至应用可能崩溃。同样,如果MyApp没有定义,我们也会得到一个错误。这些问题在新的系统都将得到解决。
1 | // Ext JS 4.x class definition |
2 | Ext . define ( ' MyApp . LoginWindow ' , { |
3 | extend : ' Ext . Window ' , |
4 | |
5 | title : ' Log in ' , |
6 | |
7 | initComponent : function ( ) { |
8 | Ext . apply ( this , { |
9 | items : [ |
10 | // as above |
11 | ] |
12 | } ) ; |
13 | |
14 | MyApp . LoginWindow . superclass . initComponent . apply ( this , arguments ) ; |
15 | } |
16 | } ) ; |
With Ext JS 4, classes can be referenced by their string name, which means we never get the errors above. The class manager is smart enough to check whether Ext.Window has been defined already, and if not, defer creation of MyApp.LoginWindow until it has been defined. We no longer need to maintain a strict load order in our applications, allowing the framework to take care of everything.
在Ext JS 4,类可以通过它们的字符串名被引用,这意味着我们将永远不会得到上述错误。类管理器会很聪明地检查Ext.Window是否已被定义,如果没有,则直到它已被定义的时候才创建MyApp.LoginWindow。因此,我们不再需要维持一个严格的加载顺序,使框架能照顾更多其它事情。
This is just the beginning though — the new class system also brings a series of new features to Ext JS classes. The first of these is the addition of mixins to the framework. Mixins define reusable sets of behavior and configuration that can be ‘mixed in’ to a class. To take advantage of this new feature in your class, simply apply them in your class definition. For example, to make your class draggable, mix in the Draggable mixin. Any number of mixins can be applied to a class, which makes them a great way to get multiple inheritance – something that has long been difficult to achieve with most JavaScript frameworks. Mixins can be defined like so:
这仅仅是个开始,新的类系统将给Ext JS 类带来一系列新的特性。首先是在框架中加入mixins特性。Mixins定义了一套可重用的行为和配置,它可以混合到类中。要在你的类中充分利用这个新特性,只需要简单的套用在你的类定义中。例如,要在你的类中加入拖动功能,可将拖动mixin混合到你的类中。你可以在你的类中混合更多的mixin,这样你就可通过该方式实现多重继承。在大多数javascript框架中,这一支难以实现。Mixins的定义请看下面代码:
1 | Ext . define ( ' Sample . Musician ' , { |
2 | extend : ' Sample . Person ' , |
3 | |
4 | mixins : { |
5 | guitar : ' Sample . ability . CanPlayGuitar ' , |
6 | compose : ' Sample . ability . CanComposeSongs ' , |
7 | sing : ' Sample . ability . CanSing ' |
8 | } |
9 | } ) ; |
Once more, all of the class names are referenced by string, so we don’t get any errors if the mixins we’re using aren’t loaded on the page yet. A class can receive any number of mixins and each mixin can be as simple as this:
另外,所有这些类名都是通过字符串引用的,因而,如果mixins还没有被加载,你也不会获得任何错误。一个类可以混合许多mixins,而每一个mixin可以简单的按以下方式定义:
1 | Ext . define ( ' Sample . ability . CanPlayGuitar ' , { |
2 | playGuitar : function ( ) { |
3 | // code to play |
4 | } |
5 | } ) ; |
Most of the classes in Ext JS can be customized by passing configuration options. Usually these configuration options can be modified and queried at runtime using getter and setter methods. These have to be maintained and add bulk to the library. Ext JS 4 comes with a special naming convention for configuration options that automatically creates these functions for you. This saves development time, ensures a consistent API and cuts down dramatically on the size of the file download. Let’s look at an example:
在Ext JS中许多类都可自定义配置选项。一般来说,这些配置选项都可在运行时使用getter和setter方法修改和获取。这些都必须在库中维持并不断扩充。Ext Js 4带有一个特别的命名约定配置选项,它可以自动为你创建这些功能。这将节省你的开放时间,并确保下载的文件的API是一致的,以及减少文件大小。让我们看一个例子:
1 | Ext . define ( ' MyClass ' , { |
2 | config : { |
3 | title : ' Default Title ' |
4 | } |
5 | } ) ; |
Here we set up the class to receive a single configuration option: title. We also provide a default value for that title, in this case ‘Default Title’. With Ext JS 4′s new class definition, new getter and setter functions are automatically created. In Ext JS 3.3, we had to manually create this boilerplate code:
在例子中,我们定义了一个类,类中有一个“title”的配置选项,而且已经将“Default Title”定义为它的默认值。在Ext JS 4新类定义中,新的getter和setter函数将自动创建,而在Ext JS 3.3中,我们不得不手动创建以下的代码:
1 | MyClass = Ext . extend ( MyBaseClass , { |
2 | title : ' Default Title ' , |
3 | |
4 | getTitle : function ( ) { |
5 | return this . title ; |
6 | } , |
7 | |
8 | resetTitle : function ( ) { |
9 | this . setTitle ( ' Default Title ' ) ; |
10 | } , |
11 | |
12 | setTitle : function ( newTitle ) { |
13 | this . title = this . applyTitle ( newTitle ) | | newTitle ; |
14 | } , |
15 | |
16 | applyTitle : function ( newTitle ) { |
17 | // custom code here |
18 | } |
19 | } ) ; |
All four of the functions above are now automatically generated by the framework. In many cases, updating the variable is enough, but sometimes we want to take some special action when we change a configuration. For example if our new class displays its title in a DOM element, we can tell it to update that element by defining it like this:
所以上述4个函数都将由框架自动生成。在许多情况,仅仅更新变量是不足够的,譬如有时候配置改变时我们需要执行特定的操作。例如,
如果新类需要将title显示在DOM元素中,我们可以通过以下定义更新元素:
1 | Ext . define ( ' MyClass ' , { |
2 | extend : ' MyBaseClass ' , |
3 | |
4 | config : { |
5 | title : ' Default Title ' |
6 | } , |
7 | |
8 | applyTitle : function ( newTitle ) { |
9 | Ext . get ( ' titleEl ' ) . update ( newTitle ) ; |
10 | } |
11 | } ) ; |
All four of these functions are generated automatically and we can override any of them as easily as we did for applyTitle above. Not only does this save you writing a lot of code in your own classes, it also significantly cuts down on the size of Ext JS and your application, meaning a smaller file download for your users.
所以这些函数在Ext JS 4中都能自动生成,当然,我们也可以很容易的重载这些函数,就如上面的applyTitle函数一样。这不仅减少了你书写类时的代码量,也大大减少Ext JS和你应用程序的文件大小,这意味着可以为用户提供更小的下载文件。
动态加载
We’ve looked at just a few of the benefits offered by the new class system — there are many more that we’ll cover later on. But now it’s time to introduce something brand new for Ext JS 4: dynamic loading.
我们已经看到了新的类系统所带来的好处,不过,这在后面还有很多。现在,是时候介绍在Ext JS 4中全新的东西:动态加载。
In every version of Ext JS so far, you’ve had to load the entire framework before using any of it. If you wanted to create an Ext.Window, it had to be downloaded already or you’d get an error. That all changes with dynaming loading in Ext JS 4. It’s as simple as this:
到目前为止的任何Ext版本,在使用之前,你都要在使用之前加载整个框架。譬如,你要创建一个Ext.window,你必须保证它已被下载,不然你会得到一个错误。在Ext JS 4中可通过动态加载加载,这很简单:
1 | Ext . require ( ' Ext . Window ' , function ( ) { |
2 | new Ext . Window ( { |
3 | title : ' Loaded Dynamically ! ' , |
4 | width : 200 , |
5 | height : 100 |
6 | } ) . show ( ) ; |
7 | } ) ; |
Here we ask Ext JS to load the Ext.Window class and then call a function when it is loaded. We can require any number of classes by passing an array to Ext.require. This just works — it’s very easy, but the real magic is under the covers. The Ext JS 4 dynamic loader is purely client-side — it requires no server-side installation. What’s more, it automatically resolves any dependencies that the loaded class has. As an example, let’s say Ext.Window looks like this:
在代码中,我们要求Ext JS加载Ext.Window类,并在加载完成执行一个函数。我们可以通过数组的方式,使用Ext.require加载任何类。这对Ext JS来说只是简单的工作,真正的魔法是在幕后。Ext JS 4的动态加载纯粹是客户端的,不需要在服务器端安装,而且它会自动下载加载类所有的依赖类。譬如,假设Ext.Window定义如下:
1 | Ext . define ( ' Ext . Window ' , { |
2 | extend : ' Ext . Panel ' , |
3 | requires : [ ' Ext . util . MixedCollection ' ] , |
4 | mixins : { |
5 | draggable : ' Ext . util . Draggable ' |
6 | } |
7 | } ) ; |
As soon as Ext JS loads the Ext.Window class, it figures out the dependencies listed in the extend, requires and mixins declared in the class. If any of these are not already present on the page, it will fetch them first before defining the Ext.Window class. The loader automatically knows how to figure out the file name for each class based on a simple convention. In this case, the following files will be loaded before our function is called:
只要Ext JS加载Ext.Window类,它将列出它的依赖类、requires和minxins定义的类。如果页面中不存在这些类,它将在定义Ext.Window类之前下载它们。加载程序将根据约定的类文件名自动下载这些类。在上面的例子中,以下类将被下载:
The Loader is recursive — if any of those files have dependencies that are not already satisfied it will keep loading files until everything is present. While you should avoid taking a file-by-file approach in production, this is immensely useful in solving one of the longest-standing irritations in developing with Ext JS – using ext-all-debug.js.
加载器是递归的。如果这些文件还有它依赖的文件,加载器将持续加载直到不再有任何依赖的文件为止。虽然在部署时要避免这种情况,但是在使用开发时解决ext-all-debug.js文件过长是非常有用的。
Until now we’ve recommended using ext-all-debug.js in development and ext-all.js in production. The debug file contains the whole framework in a readable format, but is over 60,000 lines long. This can make it difficult to debug problems – a stack trace telling you there was an exception on line 47657 of ext-all-debug.js is not especially helpful. Using the dynamic loader, the problem will be reported as line 56 of src/data/JsonReader.js, with a full stack trace and correct line numbers for each file.
直至现在,我们推荐在开发时使用ext-all-debug.js,在部署时使用ext-all.js。不过,调试文件虽然包含整个框架的可读格式,但它包含大约60000行代码,这使它难以调试。譬如,堆栈跟踪器告诉你在ext-all-debug.js在47657行有一个例外对你来说并没有任何帮助。而使用动态加载,问题将被报告为src/data/JsonReader.js的56行,这样,你可以通过堆栈跟踪到具体文件和行号。
This is a massive step forward when it comes to debugging your applications and it performs extremely well: while developing locally it’s hard to tell that the framework is being loaded dynamically. The loader also provides deadlock detection, and can be used to load files both synchronously and asynchronously.
当你在调试应用时,这是一个巨大的进步,而且它运行得非常好。在本地开发,你很难看出框架是动态加载的。加载器还提供了死锁检查,可用于同步或异步加载文件。
And if all that doesn’t entice you, don’t worry — the new class system is completely backwards compatible . Your old classes created with Ext.extend will still work, and we will continue creating the ext-all.js file which contains the entire framework.
如果这些都不是你需要的,不要担心,新的类系统完全向后兼容。你的扩展类依然可以使用,我们也会继续提供包含整个框架的ext-all.js文件。
在线演示
We’ve prepared a very simple live demo for you to experiment with and placed it online. The examples start simple and get slightly more involved as they advance. The complete example can be downloaded as a zip file and run locally where you can experiment with the code yourself – all you need is a web server to serve the files for you.
我们已经为你准备了一个简单的在线演示程序。例子由浅到深,逐步增加动态加载的文件数。完整的例子可以下载zip文件和在本地运行,这仅仅需要一个web服务器和所需要的文件。
The new class system is the basis of a massively enhanced framework for Ext JS 4. Every important class in the framework has been upgraded to be faster, more robust and easier to develop with. Over the next few weeks we’ll be introducing the advances one package at a time as we continue our countdown to Ext JS 4. Check back later this week for a look at the amazing new data package for Ext JS 4.
新的类系统是整个Ext JS 4增强框架的基础。框架中每一个重要的类都已经被升级得更快、更可靠和更容易扩展。在接下来的几个星期里,我们将继续我们的Ext JS 4倒数,每次介绍一个包。在本周晚些的时候,将会看到Ext JS 4新的数据包。
原文:Countdown to Ext JS 4: Dynamic Loading and New Class System