Ext.Loader is the heart of the new dynamic dependency loading capability in Ext JS 4+. It is most commonly used via the Ext.requireshorthand. Ext.Loader supports both asynchronous and synchronous loading approaches, and leverage their advantages for the best development flow. We'll discuss about the pros and cons of each approach:

Ext.Loader是Ext JS4動態依賴載入能力的核心。最常見的情況是通過Ext.require使用它。Ext.Loader同時支援同步和非同步載入方式。這裡,我們將討論這兩種載入方式的優缺點。

Asynchronous Loading  非同步載入

  • Advantages:  優勢

    • Cross-domain  跨域
    • No web server needed: you can run the application via the file system protocol (i.e: file://path/to/your/index .html)  不需要web伺服器:你能通過檔案系統協議執行程式。比如file://path/to/your/index.html
    • Best possible debugging experience: error messages come with the exact file name and line number  舒服的除錯體驗:錯誤資訊將返回確切的檔名字和行數。
  • Disadvantages: 缺點

    • Dependencies need to be specified before-hand   依賴必須事先指定

Method 1: Explicitly include what you need:   方法一:明確包含你想要的

// Syntax
Ext.require({String/Array} expressions); // Example: Single alias
Ext.require('widget.window'); // Example: Single class name
Ext.require('Ext.window.Window'); // Example: Multiple aliases / class names mix
Ext.require(['widget.window', 'layout.border', 'Ext.data.Connection']); // Wildcards
Ext.require(['widget.*', 'layout.*', 'Ext.data.*']);

Method 2: Explicitly exclude what you don't need: 方法二,明確排除你不想要的

// Syntax: Note that it must be in this chaining format.
Ext.exclude({String/Array} expressions)
.require({String/Array} expressions); // Include everything except Ext.data.*
Ext.exclude('Ext.data.*').require('*'); // Include all widgets except widget.checkbox*,
// which will match widget.checkbox, widget.checkboxfield, widget.checkboxgroup, etc.
Ext.exclude('widget.checkbox*').require('widget.*');

Synchronous Loading on Demand   同步載入

  • Advantages: 優勢

    • There's no need to specify dependencies before-hand, which is always the convenience of including ext-all.js before  它不需要事先指明依賴,事先包含ext-all.js是很方便的。
  • Disadvantages:缺點

    • Not as good debugging experience since file name won't be shown (except in Firebug at the moment) 除錯體驗不好,除非用Firebug除錯,否則出錯的檔案的名字不會顯示。
    • Must be from the same domain due to XHR restriction不能跨域請求,因為XHR的限制必須是相同的域名。
    • Need a web server, same reason as above   並且因為這個原因,必須有web服務。

There's one simple rule to follow: Instantiate everything with Ext.create instead of the new keyword

可以遵守一個簡單的法則:用Ext.create代替new關鍵字來例項化物件。

Ext.create('widget.window', { ... }); // Instead of new Ext.window.Window({...});

Ext.create('Ext.window.Window', {}); // Same as above, using full class name instead of alias

Ext.widget('window', {}); // Same as above, all you need is the traditional `xtype`

Behind the scene, Ext.ClassManager will automatically check whether the given class name / alias has already existed on the page. If it's not, Ext.Loaderwill immediately switch itself to synchronous mode and automatic load the given class and all its dependencies.

在後臺,Ext.ClassManager會自動檢查給定的類名或別名是否在頁面已經存在。如果沒有,Ext.Loader將會立即把它調整為同步模式,自動載入給定的類和它所有的依賴。

Hybrid Loading - The Best of Both Worlds  混合載入

It has all the advantages combined from asynchronous and synchronous loading. The development flow is simple:

混合載入方式可以結合同步和非同步載入的優勢。開發流程非常簡單:

Step 1: Start writing your application using synchronous approach.

第一步:用同步的方式寫你的程式,

Ext.Loader will automatically fetch all dependencies on demand as they're needed during run-time. For example:

Ext.Loader將會自動按照需要獲取所有的依賴,因為它們在執行時需要。例如

Ext.onReady(function(){
var window = Ext.widget('window', {
width: 500,
height: 300,
layout: {
type: 'border',
padding: 5
},
title: 'Hello Dialog',
items: [{
title: 'Navigation',
collapsible: true,
region: 'west',
width: 200,
html: 'Hello',
split: true
}, {
title: 'TabPanel',
region: 'center'
}]
}); window.show();
})

Step 2: Along the way, when you need better debugging ability, watch the console for warnings like these:

第二步:觀看控制檯的中如下的警告:

[Ext.Loader] Synchronously loading 'Ext.window.Window'; consider adding Ext.require('Ext.window.Window') before your application's code
ClassManager.js:432
[Ext.Loader] Synchronously loading 'Ext.layout.container.Border'; consider adding Ext.require('Ext.layout.container.Border') before your application's code

Simply copy and paste the suggested code above Ext.onReady, i.e:

在Ext.onReady上面新增載入依賴的程式碼:

Ext.require('Ext.window.Window');
Ext.require('Ext.layout.container.Border'); Ext.onReady(...);

Everything should now load via asynchronous mode.

這樣,所有的東西都將通過非同步的模式載入

Deployment   部署

It's important to note that dynamic loading should only be used during development on your local machines. During production, all dependencies should be combined into one single JavaScript file. Ext.Loader makes the whole process of transitioning from / to between development / maintenance and production as easy as possible. Internally Ext.Loader.history maintains the list of all dependencies your application needs in the exact loading sequence. It's as simple as concatenating all files in this array into one, then include it on top of your application.

一點很重要,動態載入只能在開發的時候在本機上使用。產品釋出的時候,所有的依賴最好是組合成一個獨一的JavaScript檔案。Ext.Loader使專案從開發維護髮布之間轉換變得很容易。在內部,Ext.Loader.history控制了你的專案所有依賴的載入順序的列表。把這個列表中的所有依賴壓縮成一個,然後把它包含在你專案的最頂部。

This process will be automated with Sencha Command, to be released and documented towards Ext JS 4 Final.

這個處理過程將會使用SenchCommand自動完成。