介紹Appcelerator於今年初發表的一套MVC框架-Alloy。它能讓Titanium App開發更有效率,程式碼更易於維護。本文介紹View的部分,Model和Controller留待下篇繼續介紹。
Alloy的歷史背景
Alloy是一個用於Appcelerator Titanium的MVC框架,其目標是提升一套架構標準,讓開發者能夠提升跨平台App的開發效率。
Titanium提供了強大的cross-compiler,開發者只要用Javascript呼叫Titanium SDK內提供的API就可以開發出功能強大的原生App。但是Titanium只是一個平台,並沒有規範應程式的架構應該如何規劃,就算連GUI的定義也要完全寫在Javascript裡面,若沒有良好的規劃,那麼在功能複雜度隨著開發進度逐漸提高的同時,記憶體漏失、維護困難、效能不彰等等問題有可能就會逐漸浮現。於是就有了TiMVC、Kranium、Extanium和IQ SDK等框架的產生,不過一直沒有那一套特別受到關注。
於是今年初Appcelerator公開了官方版本的Titanium MVC框架Alloy,企圖提出一套標準,讓開發者更容易撰寫出容易維護的跨平台程式碼。
Model-View-Contoller
MVC是軟體工程當中的一種軟體架構模式,把軟體分成三個基本部分:Model、View和Controller三個部分。這個模式可以將複雜度簡化,也讓部分程式碼可以重複利用。[list][*]Model - 包含狀態、商業邏輯與資料存取。[*]View - 提供GUI元件,負責顯示資料,並接收使用者的操作。[*]Controller - 負責協調View與Model的運作。[/list]
Alloy的特點
Alloy引用了一套網頁前端的MVC框架Backbone.js,將它改寫為適合Titanium的環境。Alloy透過慣例優於設定這樣的設計概念,讓開發者遵循Model-View-Contoller的架構,把UI和邏輯分開來,再由Alloy轉換為Titanium的程式碼,以確保App達到最佳實踐,讓App在各平台都能有高水準的表現。
使用Alloy開發之後,我們將不再需要直接在Resource目錄下撰寫程式,而是在新的app目錄下,撰寫程式。[list][*]Alloy和Titanium同樣都是基於nodejs,透過npm就能夠安裝。[*]Alloy已經整合到Titanium Studio內,不過也提供命令列工具可以使用。[/list]
View
UI的部分在傳統的Titanium App當中,需要使用Javascript來宣告,邏輯、樣式通常也是寫在一起。
Resources/app.js
var win = Ti.UI.createWindow({backgroundColor:"#fff"});
var nameLabel = Ti.UI.createLabel({text: "What is your name?",top:20, left:20});
var nameTextField = Ti.UI.createTextField({borderStyle: Ti.UI.INPUT_BORDERSTYLE_ROUNDED, left:20, top: 60, width: 200, color: "#ccc"});
var helloButton = Ti.UI.createButton({title: "Say Hello!", left:20, top: 110});
var sayHello = function(){
alert('Hello, ' + nameTextField.value);
}
helloButton.addEventListener('click', sayHello);
win.add(nameLabel);
win.add(nameTextField);
win.add(helloButton);
win.open();
Alloy XML標籤
在Alloy當中,則可使用XML來定義,以元件名稱作為標籤,把物件階層關係直接處理完。免去手動建立階層關係的程式碼。還可以如同HTML一般指定id與class,以供後續定義樣式時使用。
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>
Titanium Style Sheet
Alloy的的物件屬性可使用Titanium Style Sheet樣式表來設定。其功能與格式與css非常相近,同樣可以使用id、class和全域套用到同樣的標籤。要注意的是tss的格式與JSON相近,不同設定間要用","分隔。目前也還不能動態調整屬性,也還不支援Window > TextField這樣的階層選擇器。
app/styles/index.tss
".container": {
backgroundColor: "#fff"
},
".alignLeft": {
left: 20
},
"TextField": {
borderStyle: Ti.UI.INPUT_BORDERSTYLE_ROUNDED
},
"#nameLabel": {
top: 20,
width: Ti.UI.SIZE,
height: Ti.UI.SIZE,
color: "#000"
},
"#nameTextField": {
top: 60,
width: 200,
color: "#ccc"
},
"Button": {
width: Ti.UI.SIZE,
height: Ti.UI.SIZE
},
"#helloButton": {
top: 110
}
Device Query
另外一個Alloy的明顯好處是可以針對不同平台個別設定屬性,Alloy會在發佈時,把其他平台的設定全部移除,以節省占用空間並提升效能。
// 所有裝置均套用
"Label": {
text: 'Generic'
},
// iPhone
"Label[platform=ios formFactor=handheld]": {
text: 'iPhone'
},
// iPad和iPad mini
"Label[platform=ios formFactor=tablet]": {
text: 'iPad'
},
// Android手機和平板
"Label[platform=android]": {
text: 'Android'
},
// 瀏覽器
"Label[platform=mobileweb]": {
text: 'Mobile Web'
}