原文地址:http://docs.sencha.com/touch/2.2.0/#!/guide/components
Using Components in Sencha Touch
Contents
What is a Component?
Most of the visual classes you interact with in Sencha Touch are Components. Every Component in Sencha Touch is a subclass of Ext.Component, which means all have the ability to:
st中很多与用户交互的可视化界面都是组件。每个组件都是 Ext.Component的子类,他们都具有如下功能:
- Render themselves onto the page using a template
- 使用模板将自身渲染至页面上。
- Show and hide themselves at any time
- 在任何时候显示、影藏自己
- Center themselves on the screen
- 将自己置于屏幕中央
- Enable and disable themselves
- 使自己可用或不可用
Components also have a more advanced behavior which enables them to:
组件还有如下一些高级功能使他们能够实现如下功能:
- Float above other components (windows, message boxes, and overlays)
- 悬浮在其它组件之上(窗体、消息框)
- Change size and position on the screen with animation
- 以动画的形式改变大小或位置
- Dock other Components inside themselves (this feature is useful for toolbars)
- 使其它组件停靠于自身内部(这个特征对工具栏非常有用)
- Align to other components, allow themselves to be dragged around, make their content scrollable, and more
- 与其它组件对齐,允许自身可拖拽,使其中的内容可滚动及更多一些功能
What is a Container?
Every Component you create has all of the previosly mentioned abilities, and applications are made up of lots of components, usually nested inside one another. Containers are similar to Components, but in addition to the capabilities listed previously, they also allow you to render and arrange child Components inside them. Most apps have a single top level Container called a Viewport, which takes up the entire screen. Inside of the Viewport are child components, for example in a mail app the Viewport Container's two children Components could be a message List and an email preview pane.
你创建的每一个组件都具有上面所描述的功能,应用程序就会有很多组件构成的,经常是一个嵌套在另外一个里面。容器与组件比较相似,但是除上面列举的功能之外,他们也允许你渲染、排布子控件在容器中。很多app有个单独的沾满整个屏幕的顶级容器叫做Viewport。在Viewport内,是子组件,比如在一个邮件app中,viewport包含两个子组件,一个是邮件列表,一个是邮件预览面板。
Containers provide the following additional functionality:
容器提供如下额外功能:
- Adding child Components at instantiation and at run time
- 在实例化或运行时添加子组件
- Removing child Components
- 删除子组件
- Specifying a Layout
- 指定布局
Layouts determine how a container's child Components are laid out on the screen. In our mail app example we have used use an HBox layout, which enables us to pin the email list to the left hand edge of the screen and allow the preview pane to occupy the rest. There are several layouts available in Sencha Touch, each of which help you achieve your desired application structure, as explained in the Layout guide.
布局决定了容器中的组件是如何显示在屏幕上的。在我们的邮件app示例中,我们使用了一个Hbox布局,这种布局使我们能够将邮件列表组件停靠在页面左侧,使邮件预览面板占满剩余的空间。st中有几种布局可用,每一种布局都能达到你想要的布局效果,就像布局向导中所i描述的样。
Instantiating Components
Components are created the same way as all other classes in Sencha Touch - using the Ext.create method call. The following code sample illustrates the creation of a Panel:
与实例化其它类一样,在st中也是通过Ext.create方法来创建组件的。如下的代码展示了如何创建一个面板:
var panel = Ext.create('Ext.Panel', {
html: 'This is my panel'
});
This creates a Panel instance, configured with some basic HTML content. A Panel is a simple Component that can render HTML and that also contains other items. In the previous example we have created a Panel instance, but it does not instantly show up on the screen because items are not rendered immediately after being instantiated. This allows us to create some components and move them around before rendering and laying them out, which is significantly faster than moving them after rendering.
该代码创建了一个有一些基本的html内容的面板。面板是一个可以渲染html及包含其它子项的简单组件。在上面的例子中,我们创建了一个面板实例,但是它不会立刻展现在屏幕上,因为在实例化后子项没有立即渲染。这使我们能够创建一些组件并在渲染、展示之前能够移动它们,这通常比渲染之后再移动它们效率更高。
To show this panel on the screen we can simply add it to the global Viewport:
我们只需要将它添加到全局的Viewport中就可以将该面板展示在屏幕上:
Ext.Viewport.add(panel);
Panels are also Containers, which means they can contain other Components, arranged by a layout. Let us revisit the previous example, this time creating a panel with two child Components and an hbox layout:
面板也是容器,也就是说他们可以使用layout布局来包含通过其它组件。重新看下上面的例子,这次我们创建一个hbox布局的包含两个子组件的面板:
var panel = Ext.create('Ext.Panel', {
layout: 'hbox',
items: [
{
xtype: 'panel',
flex: 1,
html: 'Left Panel, 1/3rd of total size',
style: 'background-color: #5E99CC;'
},
{
xtype: 'panel',
flex: 2,
html: 'Right Panel, 2/3rds of total size',
style: 'background-color: #759E60;'
}
]
});
Ext.Viewport.add(panel);
This time we created three Panels - the first one is created just as before, but the inner two are declared inline using an xtype. Xtype is a convenient way of creating Components without having to go through the process of using Ext.create and specifying the full class name, instead you can provide the xtype for the class inside an object and the framework creates the components.
这一次我们创建了3个面板,第一个跟之前创建的一样,但是内部的两个是用过xtype来声明的。xtype是一种不需要通过Ext.create也不需要指定类全名而创建组件的便捷方法,你只需要为内部类提供一个xtype,框架会自动为你创建组件。
We also specified a layout for the top level panel - in this case hbox, which splits the horizontal width of the parent panel based on the 'flex' parameter of each child. For example, if the parent Panel above is 300px wide, the first child will be flexed to 100px wide and the second to 200px, because the first one was given flex: 1 and the second flex: 2.
在这个例子中,我们为外层面板设置了一个layout为hbox,然后我们通过为子面板设置flex参数将父面板在水平方向拆分为不同的宽度。例如,父面板宽度为300像素,那么第一个子面板会被分配为100像素的宽度,第二个自面板为200像素的宽度,因为第一个的flex值为1,第二个的值为2.
Configuring Components
Whenever you create a new Component you can pass it configuration options. All configurations for a given Component are listed in the "Config options" section of its class documentation page. You can pass in any number of configuration options when you instantiate the Component, and modify any of them at any point later on. For example, you can easily modify the html content of a Panel after having created it, as shown in the following example:
无论何时你创建了一个新组件,你都可以给它一些配置项。所有的配置项都列举在该组件文档的“Config options” 中。在实例化一个组件时你能够传递任意数量的配置项,并且能够在后续的任何时间点修改他们。例如,如下面的例子所示,你能够很容易的在创建了面板后修改它的html内容。
//we can configure the HTML when we instantiate the Component
var panel = Ext.create('Ext.Panel', {
fullscreen: true,
html: 'This is a Panel'
});
//we can update the HTML later using the setHtml method:
panel.setHtml('Some new HTML');
//we can retrieve the current HTML using the getHtml method:
Ext.Msg.alert(panel.getHtml()); //alerts "Some new HTML"
Every config has a getter method and a setter method - these are automatically generated and always follow the same pattern. For example, a config called 'html' automatically receives the getHtml and setHtml methods, while a config called defaultType receives the getDefaultType and setDefaultType methods, and so on.
每一个配置项都有一个getter方法和一个setter方法,这些方法是自动生成的,并且都有一样的形式。例如,一个叫html的配置项会有一个getHtml和一个setHtml方法,一个叫defaultType的配置项会有一个叫getDefaultType和一个setDefaultType的方法,等等。
Using xtype
Xtype is an easy way to create Components without having to use the full class name. This is especially useful when creating a Container that contains child Components. An xtype is simply a shorthand way of specifying a Component, for example you can use xtype: 'panel' instead of typing out Ext.panel.Panel.
xtype是一种不需要使用类全名创建组件的便捷方法。这在创建一个包含子组件的容器时会很有用。xtype只是一种标示组件的简单方法,例如,你够用用xtype:'panel'代替Ext.panel.Panel。
The following illustrates the use of xtype:
下面展示了xtype的用法:
Ext.create('Ext.Container', {
fullscreen: true,
layout: 'fit',
items: [
{
xtype: 'panel',
html: 'This panel is created by xtype'
},
{
xtype: 'toolbar',
title: 'So is the toolbar',
docked: 'top'
}
]
});
List of xtypes
This is the list of all xtypes available in Sencha Touch 2:
如下是在st2中xtype的列表:
xtype Class ----------------- --------------------- actionsheet Ext.ActionSheet audio Ext.Audio button Ext.Button component Ext.Component container Ext.Container image Ext.Img label Ext.Label loadmask Ext.LoadMask map Ext.Map mask Ext.Mask media Ext.Media panel Ext.Panel segmentedbutton Ext.SegmentedButton sheet Ext.Sheet spacer Ext.Spacer title Ext.Title titlebar Ext.TitleBar toolbar Ext.Toolbar video Ext.Video carousel Ext.carousel.Carousel carouselindicator Ext.carousel.Indicator navigationview Ext.navigation.View datepicker Ext.picker.Date picker Ext.picker.Picker pickerslot Ext.picker.Slot slider Ext.slider.Slider thumb Ext.slider.Thumb tabbar Ext.tab.Bar tabpanel Ext.tab.Panel tab Ext.tab.Tab viewport Ext.viewport.Default DataView Components --------------------------------------------- dataview Ext.dataview.DataView list Ext.dataview.List listitemheader Ext.dataview.ListItemHeader nestedlist Ext.dataview.NestedList dataitem Ext.dataview.component.DataItem Form Components --------------------------------------------- checkboxfield Ext.field.Checkbox datepickerfield Ext.field.DatePicker emailfield Ext.field.Email field Ext.field.Field hiddenfield Ext.field.Hidden input Ext.field.Input numberfield Ext.field.Number passwordfield Ext.field.Password radiofield Ext.field.Radio searchfield Ext.field.Search selectfield Ext.field.Select sliderfield Ext.field.Slider spinnerfield Ext.field.Spinner textfield Ext.field.Text textareafield Ext.field.TextArea textareainput Ext.field.TextAreaInput togglefield Ext.field.Toggle urlfield Ext.field.Url fieldset Ext.form.FieldSet formpanel Ext.form.Panel
Adding Components to Containers
As mentioned previously, Containers are special Components that can have child Components arranged by a Layout. One of the previous code samples showed how to create a Panel with two child Panels already defined inside it, but this can also be done at run time:
如前所属,容器是以能够通过layout布局向其中添加子组件来与组件区分开的。前面有一个例子展示了创建一个包含两个子面板的面板,我们也可以在运行时达到这种效果:
//this is the Panel we'll be adding below
var aboutPanel = Ext.create('Ext.Panel', {
html: 'About this app'
});
//this is the Panel we'll be adding to
var mainPanel = Ext.create('Ext.Panel', {
fullscreen: true,
layout: 'hbox',
defaults: {
flex: 1
},
items: {
html: 'First Panel',
style: 'background-color: #5E99CC;'
}
});
//now we add the first panel inside the second
mainPanel.add(aboutPanel);
In this example we created three Panels in total. First we created the aboutPanel, which we might use to tell the user a little about the app. Then we created another panel called mainPanel, which already contains a third Panel in its items configuration, with some placeholder text ("First Panel"). Finally, we added the first panel to the second panel by calling the add method on mainPanel.
在该例子中,我们总共创建了3个面板。首先我们创建了一个名叫aboutPanel的面板,它告诉用户关于app的一些信息。然后我们创建了一个叫mainPanel的面板,该面板通过items配置包含了一个显示一些占位文本(First Panel)的面板。最后,我们通过调用mainPanel的add方法将第一个面板(aboutPanel)添加至第二个面板(mainPanel)中.
In this case we gave our mainPanel another hbox layout, but we also introduced some defaults. These are applied to every item in the Panel, so in this case every child inside mainPanel will be given a flex: 1 configuration. The effect of this is that when we first render the screen only a single child is present inside mainPanel, so that child takes up the full width available to it. Once the mainPanel.add line is called though, the aboutPanel is rendered inside of it and also given a flex of 1, which causes it and the first panel to both receive half the full width of mainPanel.
在这个案例中,我们设置了mainPanel的layout为hbox,同时我们也设置了一些defaults属性。这些会应用到该面板中的每一个子项,因此在该案例中,mainPanel中的每个子项都会有flex:1这样的一个配置。产生的效果就是,当我们第一次只渲染一个子项到mainpanel时,这个子项占满了整个mainpanel。当mainpanel调用add方法后,aboutPanel也被添加到了mainPanel中并且也被赋予flex为1的配置,这使得aboutPanel和第一个面板各占据mainPanel一半的屏幕。
Likewise, it is easy to remove items from a Container using a method call such as the following:
同样的,如下所示,调用容器的方法可以很容易的移除子项:
mainPanel.remove(aboutPanel);
After this line is run, the app reverts to its previous state, with the first child panel once again taking up the full width inside mainPanel.
当上面的代码运行后,app恢复到了之前的状态,即第一个子面板占满了整个mainPanel。
Showing and Hiding Components
Every Component in Sencha Touch can be shown or hidden with a simple API call. Building on the previous mainPanel example, here is how we can hide it:
st中的没一个组件都可以通过api方法实现展示与隐藏。基于上面mainPanel的例子,这里演示下如何隐藏它:
mainPanel.hide();
This hides the mainPanel itself and any child Components inside it. Showing the Component again is predictably easy:
上面的代码隐藏了mainPanel及其中的子组件。使它再次显示出来也很简单:
mainPanel.show();
Again, this restores the visibility of mainPanel and any child Components inside it.
再次的,使得mainPanel及其中的子组件变为可见。
Events
All Components fire events, which you can listen to and take action on. For example, whenever a Text field is typed into, its 'change' event is fired. You can listen to that event by using a listeners config, as shown in the following example:
所有组件都能够触发事件,使你能够监听并采取行动。例如,无论何时一个Text field键入了值,都会触发它的change事件。你能够使用listeners配置来监听该事件,如下所示:
Ext.create('Ext.form.Text', {
label: 'Name',
listeners: {
change: function(field, newValue, oldValue) {
myStore.filter('name', newValue);
}
}
});
Every time the value of the text field changes, the 'change' event is fired and the specified listener function is called. In this case we filtered a Store by the name typed into it, but we could have provided any other function there.
每当text field的值改变了,change事件都会触发并会触发该函数。在该案例中,我们用键入的值来过滤Store字段的name字段,也可以是置于该位置的其它函数。
Lots of events are fired by Sencha Touch components, allowing you to easily hook into most aspects of an Application's behavior. They can also be specified after the Component has been created.
很多事件都是被st的组件所触发,以便你能够很容易的控制应用的行为。这些事件也可以在组件创建之后指定。
For example, assuming that you have a dashboard which polls for live updates, and that you do not want it to perform polling when the dashboard is not visible, then you could hook into the dashboard's show and hide events:
例如,假设你有一个为现场更新的投票板,你想在该投票板不可见时禁止用户投票,那么你就可以处理投票板的展示于隐藏事件(这里想了半天,也没理解英文所描述的意思):
dashboard.on({
hide: MyApp.stopPolling,
show: MyApp.startPolling
});
It is easy to apply behaviors like this to your whole app, in this case preserving battery life. Other useful events that are fired are the following:
像这种采取行动的方式在真个应用中是很容易的,这能够节省电池寿命。其它一些有用的事件如下:
Each Component has a description of the events it fires listed in its class documentation.
在每个组件的文档中都有对该组件所能触发事件的描述。
Docking
Sencha Touch has the ability to dock Components within other Containers. For example, assuming we were using an hbox layout and wanted to place a banner to the top, we could use docking which provides a way to do this without having to nest Containers inside one another:
st有能力使组件停靠在其它容器内部。例如,假设我们用了一个hbox布局,想在顶部放置一个标题栏,我们能够使用docking来实现,而不需要通过一个容器嵌套在另一个容器中来实现。
The Layout Guide has a full discussion of docking and all of the other layout options.
布局向导中有对docking及其他布局功能的详细描述。
Destroying Components
Because most mobile devices have a limited amount of memory, it is often a good idea to destroy Components when they are not needed any more. Although this is not the first thing to consider when creating an app, it is nevertheless a good way to optimize the user experience when you push the app into production. Destroying a Component is done using code as in the following example:
由于很多手机设备对内存大小有限制,所以在我们不需要该组件时销毁它是一个不错的主意。尽管这不是我们创建一个app所首先要考虑的,但当你将该应用推向产品时,它无疑是提高用户体验的一个不错的方式。销毁一个组件的方式如下所示:
mainPanel.destroy();
This removes the mainPanel from the DOM and also removes any event listeners it has set up on specific DOM elements. It also destroy any instances that the Panel uses internally, and it calls the destroy method on all of its child components. After a Component is destroyed, all of its children also no longer available, the component no longer is in the DOM and any references to it are no longer be valid.
上面的代码将mainPanel及为它设置的监听事件从dom中全部移除。它同时销毁了该panel内部的各实例,也会调用子组件的destroy方法。当一个组件销毁后,其内部的子组件也变得不可用了,该组件即从dom中移除了,并且任何对该组件的引用也是非法的。
昨晚翻译了一半,太晚了,今早来补上!