天天看點

第十一天(Using Views in Your Applications)Using Views in Your Applications在你的應用中使用視圖

原文位址:http://docs-origin.sencha.com/touch/2.2.0/#!/guide/views

Using Views in Your Applications

在你的應用中使用視圖

Contents

  1. Using Existing Components
  2. A Real World Example
  3. Custom Configurations and Behavior
  4. Advanced Configurations
  5. Usage in MVC

From a user's point of view, your application is simply a collection of views. Although much of the value of the app is in the Models and Controllers, users directly interact with the Views. In this guide we are going to look at how to create the views that build your application.

Using Existing Components

The easiest way to create a view is to use Ext.create with an existing Component. For example, if we wanted to create a simple Panel with some HTML inside, we can use the following code:

最簡單的建立視圖的方法是用Ext.create建立已經存在的元件的視圖。例如,如果我們想建立内部有一些html内容的面闆,我們可以使用下面的代碼:

Code Editor Live Preview Select Code

Ext.create('Ext.Panel', {
    html: 'Welcome to my app',
    fullscreen: true
});
           

This example creates a Panel with some html content and makes it fill the screen. Although you can create any of the built-in components this way, the best practice is to create a subclass with your specializations and then instantiate that class as follows:

這個例子建立了一個有一些html内容的面闆,并使之沾滿螢幕。盡管你可以以這種方式建立任何内部元件,最好的方式是建立一個專門的子類,然後執行個體化它,如下所示:

Code Editor Live Preview Select Code

Ext.define('MyApp.view.Welcome', {
    extend: 'Ext.Panel',

    config: {
        html: 'Welcome to my app',
        fullscreen: true
    }
});

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

The outcome is the same, but this time we have a new component that we can create any number of times. This is the pattern we normally want to follow when building our app - create a subclass of an existing component, then create an instance of it later. Let us take a look at the changes:

結果是一樣的,但是這一次我們有一個新的元件,我們可以多次建立該元件。這是我們建立app時想要遵從的方式——建立已存在元件的子類,稍後再執行個體化它。下面看下這種方式的不同點:

  • We used Ext.define for creating a new class, by extending an existing one (Ext.Panel in this case)       我們通過使用Ext.define繼承一個已經存在的類(該例中是Ext.Panel)來建立一個新的類
  • We followed the MyApp.view.MyView convention for our new view class. Although you can name it whatever you like, we suggest sticking with this naming convention    我們的新類遵從了MyApp.view.MyView的命名規範。盡管你可以給它任何名字,我們推薦使用該命名規範
  • We defined config for the new class inside a config object          我們通過config對象來定義config配置

Any of the config options available on Ext.Panel can be specified in either our new class's config block or when we come to create the class instance. When defining a subclass make sure to use the config object, when creating just pass in an object.

Ext.Panel中任何可用的config配置都可以在新類的config塊中配置,或者當我們執行個體化的時候配置。當定義一個子類時,要確定使用config對象,當建立的時候傳遞一個對象即可。

For example, the following code is based on the previous code, but with additional configuration passed in with the Ext.create call:

例如,下面的代碼是以上面的代碼為基礎的,但是在調用Ext.create時傳遞了額外的配置參數:

Code Editor Live Preview Select Code

Ext.define('MyApp.view.Welcome', {
    extend: 'Ext.Panel',

    config: {
        html: 'Welcome to my app',
        fullscreen: true
    }
});

Ext.create('MyApp.view.Welcome', {
    styleHtmlContent: true
});
           

A Real World Example

一個真實的例子

The following exmple illustrates one of the View classes from our Twitter app:

下面的例子說明了Twitter中一個視圖的例子:

Ext.define('Twitter.view.SearchBar', {
    extend: 'Ext.Toolbar',
    xtype : 'searchbar',
    requires: ['Ext.field.Search'],

    config: {
        ui: 'searchbar',
        layout: 'vbox',
        cls: 'big',

        items: [
            {
                xtype: 'title',
                title: 'Twitter Search'
            },
            {
                xtype: 'searchfield',
                placeHolder: 'Search...'
            }
        ]
    }
});
           

This code sample follows the same pattern as before - we created a new class called Twitter.view.SearchBar, which extends the framework's Ext.Toolbarclass. We also passed in some configuration options, including a layout and an items array.

上面的代碼遵從了同前面一樣的命名規範——我們建立了一個叫Twitter.view.SearchBar的類,該類繼承自架構中的Ext.Toolbar。我們也傳入了一些配置功能,包括布局及一個數組形式的子項。

In this example we used the following new options:

在這個例子中我們用到了如下新的功能:

  • requires - because we use a searchfield in our items array, we indicate the new view to require the Ext.field.Search class. At the moment the dynamic loading system does not recognize classes specified by xtype, so we need to define the dependency manually     requires——因為我們在item子項中用到了searchfield,我們指定新類需要Ext.field.Search這個類。此時,動态加載系統不能根據xtype識别類,是以我們需要手動的定義依賴。
  • xtype - gives our new class its own xtype, allowing us to easily create it in a configuration object, which is similar to the approach taken with the searchfield      xtype——給我們自己的類一個xtype,這樣,我們可以通過configuration對象很容易的建立它,就跟searchfield的建立方式一樣。

This allows us to create instances of our new view class in a couple of ways:

這使得我們能夠以多種方式建立新視圖的執行個體:

//creates a standalone instance
Ext.create('Twitter.view.SearchBar');

//alternatively, use xtype to create our new class inside a Panel
Ext.create('Ext.Panel', {
    html: 'Welcome to my app',

    items: [
        {
            xtype: 'searchbar',
            docked: 'top'
        }
    ]
});
           

Custom Configurations and Behavior

自定義配置及行為

Sencha Touch makes extensive use of the configuration system to provide predictable APIs and keep the code clean and easily testable. We strongly suggest you do the same in your own classes.

st對配置系統做了廣闊的使用,以提供可預知的api及保持代碼的整潔性和可測試性。我們強烈建議你在自己的類中也這樣使用。

Let us assume that you want to create an image viewer that pops up information about the image when you tap on it. Our design goal is to create a reusable view that can be configured with the image url, its title and its description, and that displays the title and description when you tap on it.

假設你想建立一個圖檔預覽的視圖,當你點選該視圖時彈出該圖檔的資訊。我們的設計目标是建立一個可配置圖檔url、描述及在點選時彈出标題和描述的可重用的視圖。

Most of the work around displaying images is taken care of for us by the Ext.Img component, so we subclass that as follows:

我們所關心的展示圖檔的很多工作已經被Ext.Img實作了,是以我們像下面這樣來繼承它:

Code Editor Live Preview Select Code

Ext.define('MyApp.view.Image', {
    extend: 'Ext.Img',

    config: {
        title: null,
        description: null
    },

    //sets up our tap event listener
    initialize: function() {
        this.callParent(arguments);

        this.element.on('tap', this.onTap, this);
    },

    //this function is called whenever you tap on the image
    onTap: function() {
        Ext.Msg.alert(this.getTitle(), this.getDescription());
    }
});

//creates a full screen tappable image
Ext.create('MyApp.view.Image', {
    title: 'Orion Nebula',
    description: 'The Orion Nebula is rather pretty',

    src: 'http://apod.nasa.gov/apod/image/1202/oriondeep_andreo_960.jpg',
    fullscreen: true
});
           

In this example, we have added two additional configurations to our class - title and description - which both start off as null. When we create an instance of our new class, we pass in the title and the description configs like any other configuration.

在這個例子中,我們添加了兩個額外的配置項——title和description,這兩個的初始值均為null。當我們建立新類的執行個體時,我們像其它配置項樣傳入title和description參數。

The new behavior occurs in the initialize and onTap functions. Since the initialize function is called whenever any component is instantiated, it is a good place to set up behavior such as event listeners. First we use this.callParent(arguments) to make sure the superclass' initialize function is called. This is very important, omitting this line may cause your components not to behave correctly.

新的行為發生在initialize和onTap方法中。因為initialize方法是在元件執行個體化的時候調用,是以這裡是設定行為如事件監聽器的一個很好的地方。首先,我們用this.callParent(arguments)方法確定父類的initialize方法被調用。這是非常重要的,省略這一行可能導緻你的元件不能正常工作。

After callParent, we add a tap listener to the component's element, which calls the onTap function whenever the element is tapped. All components in Sencha Touch have an element property that you can use in this way to listen to events on the DOM objects, to add or remove styling, or to do anything else you would normally do to an Ext.dom.Element.

在調用callParent後,我們向元件的元素添加了一個點選監聽器,該監聽器會在元素被點選時觸發onTap方法。st中的所有元件均有一個element屬性,你可以像上面的方式那樣在dom對象中監聽事件、添加、移除樣式或者其它 你想對Ext.dom.Element做的任何操作。

The onTap function itself uses Ext.Msg.alert to pop up some information about the image. Note that our two new configs - title and description - both receive generated getter functions (getTitle and getDescription respectively), as well as generated setter functions (setTitle and setDescription).

onTap方法用Ext.Msg.alert彈出視窗展示了圖檔的一些資訊。注意我們做的兩個新配置——title和description——每一個都會接受到自動生成的getter方法(分别是getTitle和getDescription),以及自動生成的setter方法(setTitle和setDescription)。

Advanced Configurations

進階配置

When you create a new configuration option to a class, the getter and setter functions are generated for you. For example, the config called 'border' in the following example is automatically given getBorder and setBorder functions:

當你為一個類建立一個新的配置項時,getter、setter方法會自動為你生成。例如,下面例子中的border的配置項會自動生成一個getBorder、setBorder方法。

Code Editor Live Preview Select Code

Ext.define('MyApp.view.MyView', {
    extend: 'Ext.Panel',

    config: {
        border: 10
    }
});

var view = Ext.create('MyApp.view.MyView');

alert(view.getBorder()); //alerts 10

view.setBorder(15);
alert(view.getBorder()); //now alerts 15
           

The getter and setter are not the only generated functions, there are a couple more that make life as a component author much simpler - applyBorder and updateBorder:

自動生成的方法并不僅僅是getter、setter方法,還有兩個方法會讓元件作者處理起來更友善——applyBorder和updateBorder方法:

Ext.define('MyApp.view.MyView', {
    extend: 'Ext.Panel',

    config: {
        border: 0
    },

    applyBorder: function(value) {
        return value + "px solid red";
    },

    updateBorder: function(newValue, oldValue) {
        this.element.setStyle('border', newValue);
    }
});
           

The applyBorder function is called internally any time the border configuration is set or changed, including when the component is first instantiated. This is the best place to put any code that transforms an input value. In this case we take the border width passed in and return a CSS border specification string.

applyBorder方法會在border配置被設定或修改時由系統内部調用,包括元件第一次被執行個體化。這裡是放置轉換輸入值的最好位置。這個例子中,我們用傳入的border值傳回了一個css border的字元串。

This means that when we set the view's border config to 10, our applyBorder function will make sure that we transform that value to '10px solid red'. The apply function is optional, but note that you must return a value from it or nothing will happen.

這意味着當我們這是視圖的border為10時,applyBorder方法會将該值轉換為'10px solid red'。apply方法是可選的,但是注意,你必須傳回一個值,否則什麼也不會發生。

The updateBorder function is called after the applyBorder function has transformed the value, and is usually used to modify the DOM, to send AJAX requests, or to perform any other kind of processing. In our case we are getting the view's element and updating the border style using setStyle. This means that every time setBorder is called, the DOM is immediately updated to reflect the new style.

updateBorder方法在applyBorder方法轉換值之後,該方法通常是用來修改dom、發送ajax請求或進行其他類型的處理。在我們的例子中,我們是獲得視圖的元素并用setStyle方法更新border樣式。這意味着每當setBorder被調用,dom都會應用最新的樣式。

The following code is an example of the new view in action. Click the Code Editor button to see the source - basically we created an instance of the new view and docked a spinner field at the top, allowing us to change the border width by tapping the spinner buttons. We then hooked into the Spinner's spinevent and called our view's new setBorder function from there:

下面的代碼是可運作的最新的視圖。單擊Code Editor按鈕檢視源代碼——總的來說,我們建立該視圖的一個執行個體,将spinner控件置于頂部,通過點選spinner按鈕允許我們改變border的寬度。然後我們在Spinner的spinevent事件中調用視圖的setBorder方法:

Code Editor Live Preview Select Code

//as before      
Ext.define('MyApp.view.MyView', {      
extend: 'Ext.Panel',      
config: {      
border: 0      
},      
applyBorder: function(value) {      
return value + "px solid red";      
},      
updateBorder: function(newValue, oldValue) {      
this.element.setStyle('border', newValue);      
}      
});      
//create an instance of MyView with a spinner field that updates the border config      
var view = Ext.create('MyApp.view.MyView', {      
border: 5,      
fullscreen: true,      
styleHtmlContent: true,      
html: 'Tap the spinner to change the border config option',      
items: {      
xtype: 'spinnerfield',      
label: 'Border size',      
docked: 'top',      
value: 5,      
minValue: 0,      
maxValue: 100,      
increment: 1,      
listeners: {      
spin: function(spinner, value) {      
view.setBorder(value);      
}      
}      
}      
});      

Usage in MVC

在mvc中的使用

We recommend that most Sencha Touch applications follow the MVC conventions so that your code remains well organized and reusable. As the "V" in MVC, Views also fit into this structure. The conventions around Views in MVC are very simple and follow directly from the naming convention we used throughout the previous examples.

我們推薦st應用程式遵從MVC規範,這樣你的代碼能夠保持良好的組織性和可重用性。就像MVC中的V樣,視圖也與該結構融為一體。MVC中關于視圖的規範很簡單,僅僅是遵從命名規範就像上一個例子所示。

The MyApp.view.MyView class should be defined inside a file called app/view/MyView.js - this allows the Application to find and load it automatically. If you are not already familiar with the file structure for MVC-based Sencha Touch apps, it is pretty simple - an app is just an html file, an app.js file, and a collection of models, views and controllers stored inside the app/model, app/view and app/controller directories:

MyApp.view.MyView類應該定義在app/view/MyView.js檔案中——這允許應用程式查找和自動加載它。如果你對基于MVC的st應用結構不熟,它是相當的簡單——一個app是包含一個app.js檔案,及位于app/model下的一些列模型、位于app/view下的視圖、位于app/controller下的控制器組成的:

index.html
app.js
app/
    controller/
    model/
    view/
        MyView.js
           

You can create as many views as you want and organize them inside your app/view directory. By specifying your application's Views inside your app.js file, they are loaded automatically:

你可以根據需要建立任意數量的視圖,并将它們在app/view目錄下進行組織。通過在app.js檔案中指定你的視圖,它們會被自動加載:

//contents of app.js
Ext.application({
    name: 'MyApp',
    views: ['MyView'],

    launch: function() {
        Ext.create('MyApp.view.MyView');
    }
});
           

By following the simple View naming conventions, you can easily load and create instances of View classes inside your application. The previous example does exactly that - it loads the MyView class and creates an instance of it in the application launch function. To find out more about writing MVC apps in Sencha Touch please see the intro to apps guide.

通過遵從視圖的命名規範,你可以很容易的在應用中加載、建立視圖的執行個體。上面的例子就是如此——在application的launch方法中加載了MyView類并建立愛你了它的執行個體。可以檢視 intro to apps guide擷取更多關于建立一個MVC 模型的st應用。