javascript
拥抱haXe之javascript 也玩mvc
haXe是高級語言的高級語言,可以將一個haXe程序轉換為其它的高級語言,如JS。haXe有很多優點,比如,強類型、泛型、內聯、宏、動態語言特性、命名空間……,用haXe寫程序比用JS寫程序舒服得多。本文嘗試使用haXe開發js程序,搭建一個前端mini型mvc例子。
語言:haXe。haXe編譯器可以把haXe程序編譯成js程序。
開發工具:FlashDevelop。
haXe的簡介及安裝見《html5 canvas 版 hello world! 暨haXe簡介》。開發之前,需要修改Flash Develop配置,將Tools->Program Setting->HaXeContext->Disable Compiler-based Completion 設置為 true。否則的話,haXe的自動完成會很痛苦。
項目結構如上圖。其中:index.html是演示頁面。頁面中引用的jsTest.js就是本haXe項目所生成的js文件。js程序的入口就是Main.hx中的main方法(后文詳述) 。main方法查找本頁面中的所有的haXe標簽,根據標簽的name,分派出不同的Controller出來,然后根據haXe標簽的map配置,把haXe所在節點的父節點及兄弟節點中id對應的節點映射到控制器里的字段。這樣一來,一個頁面可以對應0個、1個或多個Controller,每個頁面片段也可以對應0個、1個或多個Controller,具有極大的靈活性。
有map的存在,在Controller那邊,可以少寫很多代碼。map語法為:
(1)不同的map項由“;”分割;
(2)每個map項語法為“元素id:映射到字段的id”,如果省略掉“:”和之后的內容,則使用元素id作為映射字段的id。
這樣一來,就可以把客戶端的行為封裝成強類型的、嚴格規劃好命名空間的、有嚴格文檔的haXe代碼。開發前端時,只需要將不同的元素id映射到不同的Controller中即可實現不同的控制行為。
下面看看核心類:
(1)Page.hx
Page類封裝了一些常用的方法:
package ;
import js.Dom;
#if hack
import js.HtmlDom;
import js.Document;
import js.HtmlCollection;
#end
import js.Lib;
class Page
{
??? public static function getControllers():HtmlCollection<HtmlDom>
??? {
??????? return doc().getElementsByTagName("haXe");
??? }
??? public static inline function doc():Document
??? {
??????? return Lib.document;
??? }
??? public static function getById(id:String,node:HtmlDom=null):HtmlDom
??? {
??????? if (id == null || id == '') return null;
??????? else if (node == null)
??????? {
??????????? return doc().getElementById(id);
??????? }
??????? if (node.id == id) return node;
??????? else
??????? {
??????????? if (node.hasChildNodes() == true)
??????????? {
??????????????? var item:HtmlDom = node.firstChild;
??????????????? while (item != null)
??????????????? {
??????????????????? if (item.id == id) return item;
??????????????????? item = item.nextSibling;
??????????????? }
??????????? }
??????? }
??????? return null;
??? }
??? public static function getsByName(name:String):HtmlCollection<HtmlDom>
??? {
??????? return doc().getElementsByName(name);
??? }
}
這里有一個技巧:FlashDevelop 對haXe自動完成支持的不完善。很多js命名空間下的類不能正確支持。比如,Page.hx文件,如果不引入js.HtmlDom等三個類(紅色部分),則無法提供自動完成支持,而如果引入這三個類,則編譯報錯(這三個類已經在js.Dom中了)。解決方案就是使用一個haXe不認識的編譯開關,比如“hack”,既能讓FlashDevelop提供智能支持,又不會參與到編譯過程中去。
(2)Controller.hx
Controller.hx 類主要完成map功能,代碼為:
import js.Dom;
#if hack
import js.HtmlDom;
import js.Document;
import js.Event;
#end
import js.Lib;
class Controller
{
??? public function new(map:String = null, node:HtmlDom = null):Void
??? {
??????? if (map == null) return;
??????? var mapItems:Array<String> = map.split(';');
??????? var dy:Dynamic = this;
??????? for (i in 0 ... mapItems.length)
??????? {
??????????? var itemTxt:String = mapItems[i];
??????????? var pairs:Array<String> = itemTxt.split(':');
??????????? if (pairs.length > 0)
??????????? {
??????????????? var v0:String = StringTools.trim(pairs[0]);
??????????????? var v1:String = v0;
??????????????? if (pairs.length > 1)
??????????????? {
??????????????????? v1 = StringTools.trim(pairs[1]);
??????????????? }
??????????????? if (v0.length > 0 && v1.length > 0)
??????????????? {
??????????????????? untyped {
??????????????????????? dy[v1] = Page.getById(v0,node);
??????????????????? }???
??????????????? }
??????????? }
??????? }
??? }???
}
(3)Test.hx
Test類為具體的Controller,為頁面添加控制,代碼為:
package orc;
import js.Dom;
#if hack
import js.HtmlDom;
import js.Document;
import js.Event;
#end
import js.Lib;
class Test extends Controller
{
??? private var btnSubmit:HtmlDom;
??? private var tbOutput:HtmlDom;
??? public function new(map:String = null, node:HtmlDom = null):Void
??? {
??????? super(map, node);
??????? var self:Test = this;
??????? this.btnSubmit.onclick = function(e:Event):Void
??????? {
??????????? self.tbOutput.innerHTML = "測試一下";
??????? };
??? }
}
(4)Main.hx
Main類負責調度,且提供程序的入口,代碼為:
package ;
import js.Dom;
#if hack
import js.HtmlCollection;
import js.HtmlDom;
import js.Document;
import js.Event;
#end
import js.Lib;
import orc.Test;
class Main
{
??? static function main()
??? {
??????? var ctrls:HtmlCollection<HtmlDom> = Page.getControllers();
??????? if (ctrls != null)
??????? {
??????????? var l:Int = ctrls.length;
??????????? for (i in 0 ... l)
??????????? {
??????????????? handle(ctrls[i]);
??????????? }
??????? }
??? }
??? static function handle(node:HtmlDom):Void
??? {
??????? var className:String = node.getAttribute("name");
??????? var map:String = node.getAttribute("map");
??????? var root:HtmlDom = map != null ? node.parentNode: null;
??????? switch(className)
??????? {
??????????? case "orc.test":
??????????????? new Test(map,root);
??????? }
??? }
}
測試結果圖:
所得到的JS文件大小為12K,其中約6K為haXe的js庫。壓縮后,文件大小為 4k。如果有多個頁面的話,這個js文件會變大,但因為只下載一次,對于一般的網站或應用可以接受。
這樣做有什么好處呢?
(1)強類型,可以充分利用IDE的提示和完成功能;
(2)可以把代碼放在公共的地方,方便代碼的積累。代碼抽象好了,一般的應用,只映射一下就搞定了;
(3)代碼結構清晰。
隨著html5的到來,前端的代碼量會越來越大,越來越復雜。js太靈活了不好用。擁抱haXe吧!
?
總結
以上是生活随笔為你收集整理的拥抱haXe之javascript 也玩mvc的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 个人分析美国电脑销售现状(网店)
- 下一篇: Hadoop---在window下配置安