論文進度報告(2010/8/15):糾結的JavaScript
由於一直想要有點進度再上來報告,但是儘管距離上次報告已經三週了,現在還是沒有什麼很具體的進度出現。
老實說,JavaScript寫起來超乎預想之外的複雜。舉例來說,撰寫AJAX的程式時,要考慮到前端JavaScript、中介Controller、後端Model等多種程式的結合,程式與程式之間相依性非常高,其中一個環節出錯,都會導致整個動作失敗。而且還要考慮到各個環節中出錯時的訊息回報機制,因此非常地複雜。當然,在不熟悉AJAX的情況下總是會有許多過渡期,只是這段過渡期掙扎的比在使用CodeIgniter時還要久,就讓人有點焦急了。
因此我想藉由這篇來整理一下目前到底做了些什麼事情,接下來到底還要做些什麼,依此來整理一下頭緒吧。
熟悉JavaScript IDE:Aptana Studio
Aptana Studio是知名Java IDE Eclipse的一個插件,用來開發PHP、AJAX的網頁應用程式。而Aptana Studio也有獨立的IDE,只是就像是預先調整好Eclipse之後的客製版而已。Aptana並不像Dreamweaver那種所見即得編輯器,而是更注重於程式端的撰寫。
在前一次進度報告裡面我有提到NetBeans對於JavaScript的支援並不太好,相較之下,Aptana有幾點優勢:
- 更聰明的自動完成:不僅僅是物件的方法可以自動完成,連變數名稱(會判斷全域/區域變數)都可以呼叫自動完成。我為了搭配Packer而將區域變數皆以「_」開頭,就讓這個自動完成非常地好用。而搭配JSDoc之後,功能更為強大。
- 較為支援JSDoc:儘管Aptana使用了許多他自定的JSDoc標籤,而且要在註解寫到@時按Alt+J(因為我後來調整過,所以現在我忘了原本的快速鍵是哪個,但他就是得要按快速鍵才會叫出選單)。但是Aptana的確是比較能夠利用JSDoc來補完原本JavaScript難以辨識的物件導向特性,例如繼承(extends)。
其他的像是Outline(程式大綱)、錯誤提示等就還算普通,但也是不錯用的功能。只是他的搜尋跟取代實在是有點不太好用,太過複雜了。結果我要取代時都改貼到EmEditor去操作XD
題外話,在研究Aptana時我發現到了Aptana Jaxer這個AJAX伺服器架構,這可說是非常前瞻性的開發方式,可以讓你在原有的JavaScript程式碼當中,撰寫控制伺服器端Server中資料的AJAX程式,以簡化Client-Server之間的複雜性。這次我並沒有使用到Aptana Jaxer,但下次有機會開發AJAX專案的話,我會考慮由此著手。
有興趣的人,可以來讀讀看「初探Jaxer」來入門喔。
設計模式:觀察者模式
觀察者模式 (Obersver Pattern)是經典的軟體設計模式當中的一種,他透過介面統一來讓觀察主題(Subject)與觀察者之間的相依性鬆綁,將通知的任務集中在觀察主題中,而各觀察者自行到主題去訂閱,而通知之後行為也仍讓各觀察者自行決定。
在JavaScript這種大量依賴事件(Event),且通常是非線性、動態的執行環境中非常地適合使用觀察者模式。JavaScript是使用「EventDispatcher(事件派遣者)」來做為觀察主題,而觀察者通常是輸入function,稱之為「監聽者(Listener)」,這是JavaScript程式語言的特色發展而成一種獨特觀察者模式。
如果你用過JavaScript的addEventListener功能,其實你所用的就是觀察者模式的一種。例如你可以針對window(視窗)改變大小(resize)的事件進行觀察,程式碼通常如下:
window.addEventListener('resize', function (event) { //當視窗大小改變時,做一些動作... });
當學會觀察者模式的作法時,這簡直是JavaScript的神兵利器,許多功能都可以利用觀察者模式來實作。其中,我想到最有趣的功能是語系檔的觀察者模式。
在傳統系統開發中,語系檔通常只是供其他UI(User Interface,使用介面)元件讀取。如果語系檔有所變更時,就要在讓全部UI再來做一次讀取的動作。而這個讀取的動作通常是跟UI的初始化動作綁在一起,也就是要讓整個網頁重新讀取,才能達到語系變更的功能。
利用觀察者模式改良語系檔的話,就是把語系檔當做訂閱主題、讓各個UI的語系設置動作作為觀察者。當語系檔有所變更時,則通知各個UI的語系設置動作,以達到即時的語系變更效果。
舉例來說,在尚未讀取語系檔之前,UI會以各自的預設語系來呈現,如下圖:
再讀取語系檔的內容之後,語系檔就會通知各UI來更新語系,於是就能呈現語系檔中的中文字句,如下圖:
諸如此類的應用還可以用於AJAX接收資料的通知、Data Collection資料變更的通知等等,非常地好用,可以在未來難以預知的變化中提供多種組合的可能性。
觀察者模式可說是我在學習JavaScript中最大的收穫了。
研究Android手機版本
如果問我開發網頁程式最大的魅力在哪裡,我想應該就是HTML、JavaScript那種跨平台都可以執行的泛用性吧。
JavaScript比起Adobe Flash、Microsoft SilverLight更為泛用,甚至各平台許多的Widget也使用了JavaScript作為開發語言。而在現在的智慧型手機如Apple的iPhone、Google的Android (微軟的Windows Mobile 6以下請排除在外,WM真的是沒救了)也總算是支援較完整的JavaSript功能,也就是說,理論上我可以寫一個網頁程式,讓他同時在桌上型電腦跟手機、平板電腦上都可以正常地運作。
上圖是Android SDK中提供的Android模擬器功能,跑的是Android 2.1版本。眼尖的讀者應該可以發現到,這跟上面圖片中讀取的其實是同一個網頁,而他們的UI也幾乎是一模一樣。這就是我想要達到的效果。
由於我比較喜歡開放原始碼的Android,所以在研究手機網頁時,我是以Android為主,而不是iPhone。安裝Android SDK時著實讓我花了點功夫,最後是參考Android 模擬器安裝 (Install Android Emulator)來完成的。在之後的測試中,一開始我安裝最新的Android 2.2,但是速度不知為何很慢,於是我又測試了幾個版本,目前是使用Android 2.1在做測試平台。
我也試著去找了iPhone的測試平台來安裝,免費的只有找MobiOne,但是他的瀏覽器模擬並不是很正確,系統偵測的數字會受到外在環境影響,實在是很難在這上面開發,故放棄。
開發手機網頁的困難
然而在手機上開發網頁卻是需要注意到許多事情。以下是兩個主要碰到的問題:
找不到手機縮放的Sweet Spot
現在有許多鑽研手機網頁程式開發的方法,但大多數網頁所指的「手機(phone、mobile device)」指得都是Apple iPhone,例如Web Development For The iPhone。儘管大部分的功能在Android瀏覽器也是一樣的效果,但是像是viewport(瀏覽畫面縮放)的判斷,只有在較新的版本(似乎是Android 2.1)以上才有支援,Android 1.6並沒有支援,viewport。這種微妙的差異讓開發時遇到了不少困難。
Eric Shangkuan發表了一篇寫作Mobile Web App的準備來討論Viewport的注意事項。大部分的手機網頁開發都是將Viewport網頁縮放鎖死,不允許使用者在手機上放大縮小。而各種framework如jQTouch跟Sencha也都是如此。
舉例來說,這是jQTouch的網頁介面。在這種狀態中,使用者是不能夠縮放畫面大小。雖然實際上也的確是不需要縮放,但這是在把網頁當做純應用程式功能時才能使用。如果你的網頁是文字與應用程式功能混雜的話,那麼就會有些問題。(像是我的標註工具)
Micah在Device-scale user interface elements in iOS Mobile Safari中討論到了功能元素與手機縮放尺寸的影響。一開始讀取網頁時,手機瀏覽器會將尺寸縮放到能夠看到整個網頁寬度的大小,於是你會發現到功能按鈕就會小到讓手指很難按得到。
可是當你把手機畫面放大時,卻又發現這按鈕大到一種礙眼的程度。
這樣子的大小才是一個理想的尺寸(sweet spot)。
因此Micah提出了一個偵測尺寸縮放、並偵測現在尺寸、然後利用CSS3的「webkit-transform: scale()」來調整元素尺寸的解決方案。很遺憾的是,這似乎只能用在iPhone上。儘管我花了很多時間改良讓他能用在Android,但是實際上並不偵測到真正的縮放尺寸。
於是我放棄了,還是鎖死viewport,讓使用者乖乖用固定尺寸瀏覽網頁吧。
事後我發現到原來scale的資料可以從touch事件偵測中來取得,在JavaScript Touch and Gesture Events iPhone and Android這篇有較為詳細的介紹。下次有要研究手機網頁開發時再來研究吧。
捨棄只能在手機跟Google Chrome執行的手機網頁Framework
就如上面提過的,jQTouch跟Sencha都是專門為了手機網頁開發的Framework,其中Sencha則是結合jQTouch、Ext JS等知名JavaScript Framework的一個集大成的Framework。
他們都使用到大量的JavaScript跟CSS3,在iPhone跟Android上也都能正常運作,也可以在Google Chrome上顯示,而且非常地適合手指操作(Finger Friendly),而我也非常喜歡這種UI。
但很遺憾的是,在Firefox甚至IE當中,他們都無法正常地運作。也就是說,用Sencha或jQTouch所撰寫的網頁,幾乎就只能在手機或Google Chrome上才能開啟。
這是讓我難以接受的限制,於是最後就捨棄他們不用。只有在設計UI時,才會開啟來參考他的外觀而已。
持續改良中的單元測試
由於之前要嘗試各種技術,雖然一直是使用QUnit來建立測試頁面,但那些都不能算是真正的「單元測試」。由於AJAX是非同步的執行方式,這讓單元測試沒辦法很單純第一次做完,當然也就不知道該做的測試到底什麼時候會完成、是否成功。所以我改良了QUnit,加入預測測試數量的功能,以便更能準確地掌握到該測試的完成度。
現在單元測試也大量地使用了setTimeout來做出自動操作的功能。也許這跟實際上用手操控滑鼠來操作還是有點不太一樣,但勉強算是堪用。
此外,也不斷地調整CodeIgniter的Controller跟View架構,讓它更適合開發AJAX環境。
之後還會做一個統一計算單元測試的頁面,就如當初在CodeIgniter裡面做的一樣。這就稍晚再來進行吧。
專案進度整理
類別 | 應完成 | 已完成 | 已完成百分比 | 程式語言 |
Model | 100 | 100 | 100% | PHP |
View | 73 | 4 | 5.4% | JavaScript |
Controller | 9 | 0 | 0% | PHP |
總計 | 182 | 104 | 57.1% |
進度與上次報告來說幾乎沒有差多少,但是實際上卻已經寫了快40支程式。然而到目前為止都還是像準備作業一樣,還沒有正式進入實際開發的階段,所以感覺上根本沒有做多少事情。
目前可能是比較接近系統核心的,應該只有Selection_manager而已。就是實作了選取區域的功能。
KALS Wiki上面寫著原本預定的8/23要完成……連我自己都覺得不太可能了。還是到那一天再來看看吧。
結語
為了開發手機版介面,我跟實驗室借來了HTC Hero。使用之後果然發現到很多在電腦上用滑鼠操控無法得到的落差,使我改進了不少UI設計。(此外,Hero真好玩,Android真是不錯用)
現階段我仍在進行基礎的準備工作,目前正在撰寫跨網域檔案上傳的功能。檔案上傳很基本,但是加上一個跨網域的限制,就是很少見的技術。然而,對我正在做的標註工具來說,跨網域卻是基本的門檻而已。
因為要做的事情還是很多,多到難以看到完成的終點,所以最近多少有點喪失動力、甚為消極。
於是每天就在陌生的技術中,不斷地挑戰未知的領域,然後浮沈地掙扎吧。
嗯...是還在陣痛嗎?預產期是?
回覆刪除(一來就戳你痛處因而被揍飛...成為一顆星星)
痛倒是不怎麼痛XD
回覆刪除頂多就只有繳學費時錢包會痛而已XD