iT邦幫忙

4

Titanium Alloy-為Appcelerator Titanium設計的MVC框架 (下)

介紹Appcelerator於今年初發表的一套MVC框架-Alloy。它能讓Titanium App開發更有效率,程式碼更易於維護。本文介紹Model和Controller的部分,View請看上篇
Controller
在Alloy當中Controller包含程式邏輯以控制UI和與Model之間的資料交換。通常View與會與同名的Controller配成一對。

UI元件的參照
如以下的範例:

app/controllers/index.js

function sayHello(e) {  
    alert("Hello, "+ $.nameTextField.value + "!");
}
$.index.open();

app/views/index.xml

<Alloy>
    <Window class="container">
        <Label id="nameLabel" class="alignLeft">What is your name?</Label>
        <TextField id="nameTextField" class="alignLeft"/>
    <Button id="helloButton" onClick="sayHello" class="alignLeft">Say Hello!</Button>
    </Window>
</Alloy>

在View內的UI元件,如果有指定id,則可以透過$.id來存取。如:$.nameTextField.value就是id為nameTextField的TextField的值。另一個慣例是$.[controller的名稱],代表的是配對的View當中,最外面的元件。如:$.index就代表了Window。

如果要存取其他的View和Controller,則可使用Alloy.createController()和Controller.getView()來引用。

使用外部Library
如果想用一些外部的Javascript Library,或是不想讓程式邏輯和View有太深的耦合,則可以在app路徑下建立一個名稱為lib的目錄,把這些檔案放進去。在compile成Titanium專案的時候,這些檔案就會自動被複製到Resources目錄內。比如以下例子就是利用Moment.js這個第三方Library,把時間轉換成特定的格式。

var moment = require("moment");
moment.format("MMM Do YY");

Model
Alloy的Model繼承了Backbone的Model與Collection功能,也借用了Rails的遷移和adapter的概念處理各種儲存模式,這代表開發者可以把重點放在資料的結構和處理上,而不是和SQL或其他資料存取相關指令奮戰。目前Alloy Model可存取的資料來源包含sqlite, TitaniumSDK內建的properties和用在HTML5的localStorage等三種方式。如果要用的資料來源不是上面三種,也可以自己撰寫Sync adapter,實作Model和資料來源中間的存取方法。

Model
Alloy的Model繼承Backbone裡的Model class,以Javascript檔案的形式存在。裡面包含資料的結構和處理資料的相關邏輯(如:資料驗證等功能)。Model大致是以下這個樣子:

exports.definition = {
    config : {
        // 資料結構
        "columns": {
            "todoItem": "String",
            "done": "Bool"
        },
        // 預設值
        "defaults": {
            "todoItem": "-",
            "done": false
        }, 
        // adapter相關設定
        "adapter": {
            "type": "sql",
            "collection_name": "todoList"
        }
    },

    extendModel: function(Model) {      
        _.extend(Model.prototype, {
            // 擴充、覆蓋或實作Backbone.Model 
        });

        return Model;
    },

    extendCollection: function(Collection) {        
        _.extend(Collection.prototype, {
            // 擴充、覆蓋或實作Backbone.Collection 
        });

        return Collection;
    }
}

在Controller裡面可以使用Alloy.createModel來存取Model。比如:

var todo = Alloy.createModel("todo", {todoItem: "Study Alloy framewrok", done: false}); 
todo.save();

Collection
Alloy裡的Collection是Model的有序集合,繼承自Backbone.Collection class,通常用於準備資料讓UI元件顯示。在Alloy環境當中,如果要在Controller裡存取Collection,可使用Alloy.createCollection()將資料從資料來源讀出。

var todoList = Alloy.createCollection('todo'); 
todoList.fetch();

Model-View Binding
在Alloy內Collection資料可以同步到TableView、View、ScrollableView、CoverFlowView等UI元件,當資料改變事件發生時這些UI元件顯示的內容也會更新。

要讓Model和View可以自動同步,必須在View當中插入Collection標籤,在要同步的UI元件標籤內加上與資料同步相關的屬性。也要在重複的物件當中,比如TableViewRow中,把要顯示的資料欄為指定到對應的屬性上。

app/views/index.xml

<Alloy>
    <Collection src="todo" />
    <Window class="container">
        <TableView dataCollection="todo">
            <TableViewRow title="{todoItem}" hasCheck="(done)" />
        </TableView>
    </Window>
</Alloy>

$.win.addEventListener("close", function(){
    $.destroy();
} 

還有一點要特別注意的是,在Model-View Binding已經不需使用的時候,必須要呼叫$.destroy()釋放資源。

$.index.addEventListener('close', function() {
    $.destroy();
});

結語
從上面的介紹當中,相信大家也可以發現Alloy確實將很多本來要全部在Javascript裡面時間的功能,有系統的拆解到XML或JSON這樣的檔案格式。這代表分工上會更加方便。程式碼的長度縮短之後,在維護上也會更容易,或許在新的專案上大家可以試試看。由於文章性質的關係,本文僅介紹了Alloy的基本概念,其他功能如:讓UI元件得以重複使用的Widget,方便切換的顯示樣式的Theme,都值得花時間研究。如需詳細的操作方法與API說明,請參考Alloy官方文件


1 則留言

0
ted99tw
iT邦高手 1 級 ‧ 2013-05-01 11:42:28

讚讚讚

真是太讚了,改天用Ti來凸黑莓看看...

我要留言

立即登入留言