现在的位置: 首页 > 综合 > 正文

Sencha Touch 2 官方文档翻译之 Intro to Applications with Sencha Touch 2(ST2应用程序简介)

2012年04月14日 ⁄ 综合 ⁄ 共 14647字 ⁄ 字号 评论关闭

前言: 

读英文文档总是很难的,非母语且专业化的长篇大论容易令人气馁和浮躁,从而导致学习效率低下。

翻译是一个好方法,把学习的需求转变成翻译的任务,强迫自己不仅要看进去、看得懂,而且还要字斟句酌,然后清晰明了的表达出来,这种在翻译中学习的成果无疑是最牢固的,最后你的译文还可以帮助别人。 

这篇文章的英文原址是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 additional
modelsviews 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 加载完成,且应用程序已经做好准备的情况下执行。一般来说这里就

抱歉!评论已关闭.