Sencha Touch 2 官方文檔翻譯之 Intro to Applications with Sencha Touch 2(ST2應用程序簡介)


前言: 

讀英文文檔總是很難的,非母語且專業化的長篇大論容易令人氣餒和浮躁,從而導致學習效率低下。

翻譯是一個好方法,把學習的需求轉變成翻譯的任務,強迫自己不僅要看進去、看得懂,而且還要字斟句酌,然后清晰明了的表達出來,這種在翻譯中學習的成果無疑是最牢固的,最后你的譯文還可以幫助別人。 

這篇文章的英文原址是http://docs.sencha.com/touch/2-0/#!/guide/apps_intro

原文標題是:Intro to Applications with Sencha Touch 2Sencha Touch 2 應用程序簡介)。有意思的是,官方文檔目錄中給它的說明是 All about Applications(關於應用程序的一切) , 仔細讀來你會發現這篇文章其實是Sencha Touch MVC的總綱,對於理解Sencha Touch的MVC模式意義重大,不得不讀,所以我把它作為此系列翻譯的第一篇文章。鑒於本人水平有限,翻譯不當乃至謬誤之處在所難免,還望大家不吝賜教。 

這篇原創翻譯首先發布在自己的博客上,后續更新也都會在第一時間發布上去,敬請關注。另外我還建了一個QQ群(群號213119459)方便Sencha Touch愛好者交流,歡迎您的加入。

譯文原地址:http://www.cnblogs.com/dowinning/archive/2012/02/14/2350303.html

 

 

Intro to Applications with Sencha Touch 2

Sencha Touch 2 應用程序簡介


注:為方便起見,文中所有出現 Sencha Touch 的地方均以 ST 簡寫替代。


Sencha Touch 2 is optimized around building applications that work across multiple platforms. To make the writing of applications as simple as possible, we provide a simple but powerful application architecture that leverages the MVC (Model View Controller) pattern. This approach keeps your code clean, testable and easy to maintain, and provides you with a number of benefits when it comes to writing your apps:

ST2 專為構建可跨多平台工作的(web)應用程序而優化。為盡可能的方便您編寫應用程序,我們提供了一個雖簡單但卻強大的應用程序架構,它可以視作是對MVC(Model/模型、View/視圖、Controller/控制器)模式的擴充。使用這種模式編寫應用程序,不僅可以保證你的代碼干凈、便於測試、容易維護,還能得到如下好處:

  • History Support: full back button support inside your app, and any part of your app can be linked to 
    訪問歷史支持:你的應用將獲得完整的后退按鈕功能,其中的任意部分都可以被鏈接到
  • Deep Linking: share deep links that open any screen in your app, just like linking to a web page 
    深度鏈接:如同以往鏈接到某一個web頁面一樣,深度鏈接可以打開你應用程序中的任意屏幕
  • Device Profiles: easily customize your application's UI for phones, tablets and other devices while sharing all of the common code 
    設備配置文件:共享通用代碼的同時,輕松為手機、平板電腦還有其他設備定制應用程序UI(用戶界面)

 

 

Anatomy of an Application

應用程序結構解析 

 



An Application is a collection of Models, Views, Controllers, Stores and Profiles, plus some additional metadata specifying things like application icons and launch screen images.

ST 應用程序是一個由 Model、View、Controller、Store、Profile 組成的集合,外加一些額外指定的元數據,比如 icon 圖標和啟動界面顯示的圖片。 

您的瀏覽器可能不支持顯示此圖像。

  • Models: represent a type of object in your app - for example an e-commerce app might have models for Users, Products and Orders 
    數據模型:在應用程序中表示一種數據模型,比如一個電子商務應用程序可能會有用戶、產品、訂單等不同的數據模型
  • Views: are responsible for displaying data to your users and leverage the built in Components in Sencha Touch 
    視圖:負責將數據展示給用戶,並擴充 Sencha Touch 的內置組件。(譯者注:你可以理解為用戶界面的一個個組成部分)
  • Controllers: handle interaction with your application, listening for user taps and swipes and taking action accordingly 
    控制器:處理應用程序的交互,偵聽用戶的輕觸、猛擊(譯者注:真實意思是長按?)等事件並做出相應的響應 
  • Stores: are responsible for loading data into your app and power Components like Lists and DataViews 
    數據存儲器:負責把數據加載到你的應用並以列表(List)或者數據視圖(DataView)等形式表現出來
  • Profiles: enable you to easily customize your app's UI for tablets and phones while sharing as much code as possible 
    設備配置:可以使你為平板電腦和手機等不同設備,輕易定制應用程序用戶界面,並盡可能多的共享代碼 

 
The Application is usually the first thing you define in a Sencha Touch application, and looks something like this:

Application 對象通常是你開發一個ST應用時需要定義的第一個東西,類似下面這樣子:

Ext.application({

    name: 'MyApp',

    models: ['User', 'Product', 'nested.Order'],

    views: ['OrderList', 'OrderDetail', 'Main'],

    controllers: ['Orders'], 

    launch: function() {

        Ext.create('MyApp.view.Main');

    }

});

 
The name is used to create a single global namespace for your entire application, including all of its models, views, controllers and other classes. For example, an app called MyApp should have its constituent classes follow the pattern MyApp.model.UserMyApp.controller.Users,MyApp.view.Main etc. This keeps your entire app under a single global variable so minimizes the chance of other code on the page conflicting with it.

如代碼所示,application 構造參數中有個 name 屬性,它為你的應用程序創建一個唯一命名空間,其下包含了該應用全部的 model、view、controller 還有其他 class(類),比如一個叫做 MyApp 的應用就應該遵循以下形式來組織:MyApp.model.UserMyApp.controller.UsersMyApp.view.Main 等,這可以保證你整個的應用程序都處在一個唯一全局變量下,從而最大限度降低代碼沖突的可能性。

The Application uses the defined modelsviews and controllers configurations to automatically load those classes into your app. These follow a simple file structure convention - models are expected to be in the app/model directory, controllers in the app/controller directory and views inside the app/view directory - for example app/model/User.jsapp/controllers/Orders.js and app/view/Main.js.

應用程序會按照你在 application 構造函數中定義好的 modelsviews 和 controllers 屬性成員來自動加載它們對應的 class(類)到當前應用,ST2 架構約定的文件結構如下:model 都放在 app/model 目錄,controller 都放在 app/controller 目錄,view 則放在 app/view 目錄,比如 app/model/User.jsapp/controller/Orders.js,  app/view/Main.js(譯者注:原文中 Orders.js 文件的路徑是錯的,modelviewcontroller 這三個目錄名稱都沒有 s

Note that one of the models we specified was different to the others - we specified the full class name ("MyApp.model.nested.Order"). We're able to specify the full class name for any of those configurations if we don't follow the normal naming conventions. See the Dependencies section of the Ext.app.Application docs for full details on how to specify custom dependencies.

注意 models 屬性中有一個成員的定義跟其他不一樣,("MyApp.model.nested.Order"),除了遵循上述的常規命名格式以外,我們還可以使用完整類名的方式來定義這些配置,換言之 application 構造函數中的 models、views、controllers 這些參數屬性都可以用完整類名方式來定義,想了解更多關於如何定義依賴項的細節,請參見文章 Dependencies section of the Ext.app.Application docs ( Ext.app.Application 文檔中的 Dependencies 章節)



Controllers

控制器 

 



Controllers are the glue the binds an application together. They listen for events fired by the UI and then take some action on it. This helps to keep our code clean and readable, and separates the view logic from the control logic.

Controller(控制器)就像膠水一樣粘合出一個完整的應用程序,它們偵聽UI界面觸發的事件,然后做出相應的動作,還能夠讓我們的代碼更簡潔,可讀性好,從而把界面邏輯和控制邏輯隔離開來。

For example, let's say you require users to log in to your app via a login form. The view in this case is the form with all of its fields and other controls. A controller should listen to tap event on the form's submit button and then perform the authentication itself. Any time we deal with manipulating data or state, the controller should be the class that activates that change, not a view.

假如你需要用戶通過一個 login 表單來登錄你的應用程序,此時的 view(視圖)就是這個包含了所有字段和其他元素的表單,而它的 controller(控制器)要做的就是偵聽表單提交按鈕的點觸事件並進行身份驗證,每次我們要處理數據或者狀態的時候,這個 controller(控制器)才是應該起作用的類,而不是 view(視圖)。

Controllers expose a small but powerful set of features, and follow a few simple conventions. Each Controller in your application is a subclass of Ext.app.Controller (though you can subclass existing Controllers, so long as it inherits from Ext.app.Controller at some point). Controllers exist in the MyApp.controller.* namespace - for example if your app had a Sessions controller it would be called MyApp.controller.Sessions and exist in the file app/controller/Sessions.js.

Controller(控制器)通過一些簡單的約定,展示了一套雖小但卻很強大的特性。應用程序的每一個 controller(控制器)都是 Ext.app.Controller 的一個子類,當然你也可以繼承現有的 controller ,只要它也是繼承自 Ext.app.Controller controller(控制器)都存在於 MyApp.controller.* 命名空間,例如你的應用有一個叫做 Sessions controller ,那么它的完整命名空間將會是 MyApp.controller.Sessions 並且被定義在 app/controller/Sessions.js 文件中。

Although each Controller is a subclass of Ext.app.Controller, each one is instantiated just once by the Application that loaded it. There is only ever one instance of each Controller at any one time and the set of Controller instances is managed internally by the Application. Using Application's controllers config (as we do above) loads all of the Controllers and instantiates them automatically.

每個 controller(控制器)都是 Ext.app.Controller 的一個子類,加載它的應用程序也只會對它實例化一次,應用程序自己會控制每個 controller(控制器)在同一時間只有一個實例。我們使用 Application 對象的 controllers 參數來加載 Controller(控制器)並且會自動實例化它們。


A simple example

一個簡單例子

Here's how we might quickly define the Sessions controller described above. We're using 2 Controller configurations here - refs and control. Refs are an easy way to find Components on your page - in this case the Controller will look for all Components that match the formpanel xtype and assign the first one it finds to the loginForm property. We'll use that property in the doLogin function later.

這里將演示如何快速定義上面描述的 Sessions 控制器,我們將使用 controller 的兩個配置參數,refs 和 control ,refs 是找到頁面組件的簡單方式,這個例子里 controller(控制器)會搜索所有 formpanel 類型的控件,然后將找到的第一個賦值給 loginForm 屬性,這個屬性會在下面的 doLogin 方法中用到。

The second thing it does is set up a control configuration. Just like refs, this uses a ComponentQuery selector to find all formpanel xtypes that contain a button inside them (for example, this will find the Submit button in our hypothetical login form). Whenever any button of this type fires its tap event, our Controller's doLogin function will be called:

然后我們要做的是配置 control 參數,像 refs 一樣使用 ComponentQuery 選擇器來查找所有包含 button 控件的 formpanel 下的 button 控件,在本例中,將會得到我們登陸表單當中的提交按鈕,任意一個符合此條件的 button 觸發了tap事件,controller(控制器)都會去調用其中的 doLogin 函數。

Ext.define('MyApp.controller.Sessions', {

    extend: 'Ext.app.Controller',

    config: {

        refs: {

            loginForm: 'formpanel'

        },

        control: {

            'formpanel button': {

                tap: 'doLogin'

            }

        }

   },

    doLogin: function() {

        var form   = this.getLoginForm(),

            values = form.getValues();

        MyApp.authenticate(values);

    }

});

 
The doLogin function itself is quite straightforward. Because we defined a 'loginForm' ref, the Controller automatically generates agetLoginForm function that returns the formpanel that it matches. Once we have that form reference we just pull the values (username and password) out of it and pass them to an authenticate function. That's most of what Controllers ever do - listen for events fired (usually by the UI) and kick off some action - in this case authenticating.

doLogin 函數本身非常容易理解,由於我們前面定義了一個叫做 loginForm 的 ref ,controller(控制器)將會自動生成一個叫做 getLoginForm 的函數用來返回該 formpanel (也就是這個叫做 loginForm 的 ref 啦),待完成對這個 form 的引用之后,我們只需要把其中的值(用戶名和密碼)取出來然后傳遞給 authenticate(身份驗證)函數即可,上述就是一個 controller(控制器)能做的絕大部分事情了 —— 偵聽事件(通常由UI觸發)然后做點別的什么事情,比如用戶身份驗證。

For more on what Controllers are and what capabilities they possess see the controllers guide.

想了解更多關於 controller(控制器)是什么和能做什么的知識,請查看 controllers guide (控制器指南)頁面。 



Stores

數據存儲器 

 



Stores are an important part of Sencha Touch and power most of the data-bound widgets. At its simplest, a Store is not much more than an array of Model instances. Data-bound Components like List and DataView just render one item for each Model instance in the Store. As Model instances are added or removed from the Store events are fired, which the data-bound Components listen to and use to update themselves.

Store(數據存儲器)是 ST 的重要組成部分,它能夠實現大部分的組件數據綁定工作。簡單來說,一個 store(數據存儲器)就是一個由 Model(數據模型)的實例組成的數組,諸如 List 和 DataView 這類的數據綁定型控件,他們會為 Store(數據存儲器)中的每一個 Model(數據模型)實例渲染一個 item(這里指數據綁定控件的子項),Store(數據存儲器)中的 Model(數據模型)實例被添加或者刪除的時候會觸發數據綁定控件的相應事件,從而實現控件的更新。

While the Stores guide has much more information on what Stores are and how they fit in with Components in your app, there are a couple of specific integration points with your Application instance that you should be aware of.

Stores guide (數據存儲器指南)網頁上有更多信息,比如到底什么是 Store(數據存儲器)以及它們在你的應用程序中是如何去與 Component(組件)協調工作的,那里還有幾個你必須注意的特殊要點,均與 Application 實例有關。 



Device Profiles

設備配置文件 

 



Sencha Touch operates across a wide range of devices with differing capabilities and screen sizes. A user interface that works well on a tablet may not work very well on a phone and vice versa so it makes sense to provide customized views for different device types. However, we don't want to have to write our application multiple times just to provide a different UI - we'd like to share as much code as possible.

ST 可以跨越非常廣泛的平台,盡管這些平台擁有不同的性能和屏幕尺寸。一個在平板電腦上工作良好的UI並不一定適應手機界面,反之亦然。所以為不同設備提供定制過的不同 view(視圖)是一件很有必要的事情。畢竟誰也不想僅僅為了提供不同的 UI 就得把應用程序重寫 N 次,我們希望可以讓不同設備共享盡可能多的代碼。

Device Profiles are simple classes that enable you to define the different types of devices supported by your app and how they should be handled differently. They are opt-in, so you can develop your app without profiles at first and add them in later, or never use them at all.Each profile simply defines an isActive function that should return true if that profile should be active on the current device, plus a set of additionalmodelsviews and controllers to load if that profile is detected.

Device Profile(設備配置)是一些簡單的類,這些類能讓你定義程序支持的不同類型設備以及如何處理這些不同。Device Profile(設備配置)不是必需的,你可以一開始不定義Profile 以后再添加,甚至永遠不定義它們。每個 profile 都要定義一個簡單的 isActive 函數,用來返回當前設備上是否應該啟用此 profile(換言之,該 profile 是否匹配當前的設備) ,並為該 profile 載入一堆(當前 profile 中約定的)model ,view 和 controller 。

To app Profile support to your app you just need to tell your Application about those Profiles and then create Ext.app.Profile subclasses for them:

要為你的應用程序添加 Profile 支持功能(懷疑英文原文第一個 app 應為 add ),你只需告訴應用程序有哪些 profile 需要被支持,然后為它們各自創建Ext.app.Profile 的子類即可。

Ext.application({

    name: 'MyApp',

    profiles: ['Phone', 'Tablet'], 

    //as before

});

 
By defining the profiles above the Application will load app/profile/Phone.js and app/profile/Tablet.js. Let's say that the tablet version of the app enables additional capabilities - for example managing groups. Here's an example of how we might define the Tablet profile:

如上面代碼所示,應用程序會加載 app/profile/Phone.js 和 app/profile/Tablet.js 兩個文件,我們假定平板電腦的版本將會擁有一些額外的能力,比如對組的管理功能,下面的例子將告訴我們該如何定義tablet的profile:

Ext.define('MyApp.profile.Tablet', {

    extend: 'Ext.app.Profile', 

    config: {

        controllers: ['Groups'],

        views: ['GroupAdmin'],

        models: ['MyApp.model.Group']

   }, 

   isActive: function() {

       return Ext.os.is.Tablet;

   
}); 

 
The isActive function will return true whenever the application is run on what Sencha Touch determines to be a tablet. This is a slightly subjective determination because there is a near-continuous spectrum of device shapes and sizes with no clear cutoff between phones and tablets. Because there is no foolproof way to state which devices are tablets and which are phones, Sencha Touch's Ext.os.is.Tablet is set to true when running on an iPad and false otherwise. If you need more fine grained control it's easy to provide any implementation you like inside your isActive function, so long as it returns true or false.

當ST檢測到你的設備是一台平板電腦時,isActive 函數將會返回 true 。鑒於現在不斷涌現出的各種新設備,其外形和尺寸已經越來越模糊了手機和平板電腦的界限,故而我們無法找到傻瓜化的方式去界定哪些設備是平板哪些設備是手機,ST 的 Ext.os.is.Tablet 只有在 iPad 上運行的時候將被設定為 true ,其他則為 false ,如果你需要更好的判斷和控制,你可以通過在 isActive 函數中進行更多你希望的檢測,來控制它返回 true 還是 false 。

You should make sure that only one of your Profiles returns true from its isActive function. If more than one of them returns true, only the first one that does so will be counted and the rest ignored. The first one that returns true will be set as the Application's currentProfile, which can be queried at any time.

你必須保證只有一個 profile 的 isActive 函數可以返回 true ,如果超過一個的話,只有第一個會有效而其他將被忽略,第一個返回 true 的 profile 將被視作應用程序的 currentProfile(當前 profile ),你也可以隨時獲取到當前 profile 的值。

If the detected currentProfile has defined additional models, views, controllers and stores these will be automatically loaded by the Application, along with all of the modelsviews and controllers defined on the Application itself. However, all of the dependencies named in the Profile will be prepended with the Profile name unless the fully-qualified class name is provided. For example:

如果檢測到的當前profile定義了額外的 model(數據模型)、view(視圖)、controller(控制器)、store(數據存儲器),它們會與 application 當中定義的其他元素一起被自動加載。而所有在 profile 中定義的元素路徑前面都會被加上 profile 的名稱,除非你對它們定義了完整路徑的類名,如下所示。 

  • views: ['GroupAdmin'] will load app/view/tablet/GroupAdmin.js 
    views: ['GroupAdmin'] 將會加載 app/view/tablet/GroupAdmin.js (因為 GroupAdmin 是在 tablet profile 中配置的)
  • controllers: ['Groups'] will load app/controller/tablet/Groups.js 
    controllers: ['Groups'] 將會加載 app/controller/tablet/Groups.js (同上)
  • models: ['MyApp.model.Group'] will load app/model/Group.js 
    models: ['MyApp.model.Group'] 將會加載 app/model/Group.js (因為使用了完整路徑)

 
Most of the time a Profile will only define additional controllers and views as the models and stores are typically shared between all variants of the app. For a more detailed discussion of Profiles see the device profiles guide.

絕大多數情況下,profile 只會定義額外的 controller 和 view ,因為 model 和 store 一般情況下都會被共享。關於 profile 的更多細節,請訪問 device profiles guide 頁面(設備配置指南)。 



Launch Process

ApplicationLaunch 

 



Each Application can define a launch function, which is called as soon as all of your app's classes have been loaded and the app is ready to be launched. This is usually the best place to put any application startup logic, typically creating the main view structure for your app.

每個 Application 對象都會定義一個 launch 函數,它將會在你應用程序所需的全部 class 加載完成,且應用程序已經做好准備的情況下執行。一般來說這里就是你用來放置應用程序啟動邏輯的最好位置了,比如你可以在這里為你的應用創建主要 view 框架。

In addition to the Application launch function, there are two other places you can put app startup logic. Firstly, each Controller is able to define an init function, which is called before the Application launch function. Secondly, if you are using Device Profiles, each Profile can define a launch function, which is called after the Controller init functions but before the Application launch function.

除了 Application 中的 launch 函數之外,還有兩個地方可以放置啟動邏輯:第一,每個 controller(控制器)都可以定義一個 init 函數,這個函數將會運行在 application 的 launch 運行之前;第二,如果你使用了設備 profile ,每一個 profile 都可以定義一個 launch 函數,他將會在 controller(控制器)的 init 之后和 application 的 launch 之前被調用。

Note that only the active Profile has its launch function called - for example if you define profiles for Phone and Tablet and then launch the app on a tablet, only the Tablet Profile's launch function is called.

注意只有活動 profile 的 launch 函數才會被調用,比如你分別定義了 phone 和 tablet 的 profile ,現在是在 tablet 上運行它,那么只有 tablet profile 中的 launch 函數會被調用到。

  1. Controller#init functions called 
    Controller init 首先被調用
  2. Profile#launch function called 
    其次是當前 Profile launch 被調用 
  3. Application#launch function called 
    然后 Application launch 被調用 
  4. Controller#launch functions called 
    最后是其他 controller launch 被調用

 
When using Profiles it is common to place most of the bootup logic inside the Profile launch function because each Profile has a different set of views that need to be constructed at startup.

當使用 profiles 的時候,最好把啟動邏輯代碼放在 profile 的 launch 里面,因為每個 profile 可能需要調用不同的 view 來構建啟動界面。 



Routing and History Support

路由和訪問歷史支持 

 



Sencha Touch 2 has full Routing and History support. Several of the SDK examples, including the Kitchen Sink, use the history support to enable the back button to easily navigate between screens - especially useful on Android.

ST2 具有完整的路由和訪問歷史支持,SDK 中的好幾個例子,包括 Kitchen Sink ,都使用了歷史路徑支持,以實現通過 back 按鈕可以輕易的在屏幕之間回退導航,這一點在 Android 上尤其有用。

There will be full documentation on the history support from beta 1 onwards. As of 2.0.0 PR4 the best place to learn about Sencha Touch 2's history support is kitchen sink example, which features lots of documentation on the routing and state restoration required for history support.

Beta 1 中有關於訪問歷史支持的完整文檔,對於 2.0.0 PR4 來說,學習 ST2 的這個功能的最好地方是 Kitchen Sink 例子,這個例子在路由和狀態返回等需要訪問歷史支持的地方有很多說明。 



Further Reading

延伸閱讀 

 



There are several more guides on using the application architecture with Sencha Touch 2:

關於 ST2 的應用程序架構方面,還有幾個其他的學習頁面供參考。

 

全文完,尊重他人勞動,轉載請注明出處,有問題煩請指正,多謝。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM