Fork me on GitHub

JSBorn 特徵

了解JSBorn 功能與內建提供的核心與插件,讓您能更快速模組您的JS。

Alpha版本,還有很多問題和需要加強的地方,若有問題或想法可 聯絡我,覺得不錯記得給個

定義物件

載入jsborn後,您可以馬上用以下方式定義一個物件,以下範例定義一個名為 org.jsborn.instance 的物件。

JSB.cls("org.jsborn.instance", {
	//當物件被JSB.create時,將會突發此函式
	initialize: function() {

		console.log("log","org.jsborn.instance initialize!");

	}

})
var _ns_instance = JSB.create("org.jsborn.instance");
org.jsborn.instace initialize!

傳入初始化資料

...

	initialize: function(obj) {

		console.log(obj.name);

	}

...
var _ns_instance = JSB.create("org.jsborn.instance",{name:"hello world!"});
hello world!

關於物件的命名

關於物件的命名 org.jsborn.instance 是會影響JSBorn動態載入class的位置,詳細可以查看 import 機制

定義函式

您可以在在物件內,定義多個函式。

編輯範例
JSB.cls("org.jsborn.instace", {

	helloWorld:function(){
		console.log("call:helloWorld");
		this._call_private();
	},

	setData:function(str_data){
		this.str_data = str_data;
	},

	getData:function(){
		return this.str_data;
	},

	initialize: function(options) {

	},

	_call_private:function(){
		console.log("call:_call_private");
	}

})
var _ns_instance = JSB.create("org.jsborn.instance");
_ns_instance.helloWord();
console.log(_ns_instance.getData());
_ns_instance.setData("set data to class");
console.log(_ns_instance.getData());
call:helloWorld
call:_call_private
undefined
set data to class

關於公用函式與私有函式

在JSBorn上是沒有公用函式與私有函式,而作者單純是用 下劃線法 辨識私有函式,而用 小駝峰式命名法 來辨識公用函式

繼承物件

你也可以用JSBorn定義的物件來實現繼承的功能:

extend :繼承

abstr :抽象

single :單一實例/Singleton

編輯範例
JSB.cls("org.jsborn.parent", {

	abstr:true,

	myname:"i am parent",

	parentMethod:function(){
		console.log("call::parentMethod!");
	},

	initialize: function(options) {

		console.log("org.jsborn.parent initialize!");

	}

});

JSB.cls("org.jsborn.node", {
	//繼承物件org.jsborn.parent
	extend:"org.jsborn.parent",

	single:true,

	initialize: function(options) {

		console.log("org.jsborn.node initialize!");

	}

});
var _ns_node = JSB.create("org.jsborn.node");
_ns_node.parentMethod();
console.log(_ns_node.myname);
org.jsborn.node initialize!
org.jsborn.parent initialize!
call::parentMethod!
i am parent

如果希望父層先初始化,則 this.SUPER()

編輯範例
...
JSB.cls("org.jsborn.node", {
	//繼承物件org.jsborn.parent
	extend:"org.jsborn.parent",

	initialize: function(options) {

		this.SUPER()
		...
	}

});

最後輸出如下:

org.jsborn.parent initialize!
org.jsborn.node initialize!
...

關於繼承

JSBorn支援無限繼承,不支援多重繼承,雖然技術上行,但作者認為會混亂,

若繼承的物件沒有事先載入,JSBorn會根據所繼承的物件名字自動執行import的動作 ,詳細可見 extend 機制

物件事件

您可以自訂事件來監聽你所定義的物件以達到callback的效果

以下範例是監聽物件之間傳送事件

編輯範例
JSB.cls("org.jsborn.node", {

    triggerCallback: function (str_event) {
        //傳送事件給監聽此物件的物件
        this.dispatchEvent(str_event, this);
    },

    initialize: function (options) {

    }

})

JSB.cls("org.jsborn.instance", {

    getNode: function () {

        return this._ns_node;

    },

    initialize: function (options) {

        var dd = this;
        //建立物件node
        dd._ns_node = JSB.create("org.jsborn.node");
        //對物件node監聽事件
        dd._ns_node.addListener("iamcallback", this._node_callback);
        //你可以對物件監聽多個事件
        dd._ns_node.addListener("multievent", this._node_multievent);

    },
    //接送物件Node的iamcallback事件
    _node_callback: function (e, scope) {
        console.log("_node_callback!");
        //移除事件
        scope.removeListener("iamcallback");
    },
    //接送物件Node的multievent事件
    _node_multievent: function (e, scope) {
        console.log("_node_multievent!");
        //移除事件
        scope.removeListener("multievent");
    }

});
var _ns_instance = JSB.create("org.jsborn.instance");
_ns_instance.getNode().triggerCallback("iamcallback");
_ns_instance.getNode().triggerCallback("multievent");
_node_callback!
_node_multievent!

以下範例是使用一般callback

編輯範例
JSB.cls("org.jsborn.node", {

	triggerCallback:function(){
		dd._func_cb();
	},

	initialize: function(options) {

		dd._func_cb = options;

	}

})

JSB.cls("org.jsborn.instance", {

	...

	initialize: function(options) {
		
		var dd = this;

		dd._ns_node = JSB.create("org.jsborn.node",function(){
			console.log("_node_callback!");
		});

	}

});
var _ns_instance = JSB.create("org.jsborn.instance");
_ns_instance.getNode().triggerCallback();
_node_callback!

關於事件

iamcallbackmultievent是作者隨意自訂的事件,表示事件是可以按照你所要的名字自訂,詳細可看 物件的事件

引用物件

當檔案分離,但又不希望在html預先載入需要的js時,可以使用 imports

檔案分離如下:


	source/
	├── jsborn/
	│   ├── plugin/
	│   │   ├── ...
	│   ├── core/
	│   │   ├── ...
	│   ├── jsborn.js
	├── org/
	│   ├── jsborn/
	│   │   ├── Model.js
	│   │   ├── Node.js

org.jsborn.Node 需要用到 org.jsborn.Model 時,則 imports

JSB.cls("org.jsborn.Node", {
	//注意class name是對應目錄
	imports:[
		"org.jsborn.Model"
	],

	initialize:function(){

		//因為使用import的關係,執行動態載入Model.js,所以才能順利的建立Model物件
		var _cls = JSB.create("org.jsborn.Model");

	}

});

關於Imports

imports 支援多重載入。

若想要改變imports的解析與目錄,詳細可見 import 機制

刪除物件

由於物件化的關係,JSBorn對物件提供了 destroy 函式以便GC回收

以下範例監聽了 destroy callback

編輯範例
JSB.cls("org.jsborn.instance", {

	initialize: function(options) {
		this.addListener("destroy",this._do_destroy);
	},

	_do_destroy:function(){
		console.log("org.jsborn.instance destroy!");
		//do something.
	}

});
var _ns_instance = JSB.create("org.jsborn.instance");
_ns_instance.destroy();
org.jsborn.instance destroy!

關於事件

更多的關於物件的說明,可查看 物件的文件

使用插件

你可以自己編寫或使用別人所提供的插件來擴充您所定義的物件

以下範例使用JSBorn內建插件 jsborn.plugin.model 來擴充您的物件

編輯範例
JSB.cls("org.jsborn.instance", {
	//使用jsborn內建插件
	plugins:[
		"jsborn.plugin.model"
	],

	initialize: function(options) {
		//addModel函式是因為載入model才能使用。
		//以下是model插件偵測資料一旦被改變則執行callback
		this.addModel('key',{name:"hello"}).addListener("model-modify",function(e,scope,obj){

			console.log("name change to: "+ obj.name);
			
		});

	},

	changeData:function(){
		//
		this.setModel("key",{name:"hello world"});

	}

});
var _ns_instance = JSB.create("org.jsborn.instance");
_ns_instance.changeData();
name change to: hello world

關於插件

若插件沒有事先載入,JSBorn會根據插件名字自動執行import的動作,詳細可見 import 機制

若要了解如何編寫插件,詳細可見 擴充文件

關於JSBorn提供的內建插件,詳細可見 API 文件

擴充JSB是指對JSB全域變數進行擴充,目前JSBorn提供兩個內建的擴充:ChannelModel

JSBorn內建的JSB擴充預設都不會載入,只有您需要使用到時才會載入

若要預設載入全域擴充,可以查看 JSB.setConfig

若需要自行對JSB擴充,你可以到此查看 開發者 文件


Channel物件 jsborn.core.channel

Channel 能讓物件加入不同的事件頻道,就如收音機接收電臺一樣,接收事件。

以下範例:建立3個無關係的物件,但是透過 Channel 來達到事件傳遞。

編輯範例
JSB.cls("org.jsborn.a", {
    //載入channel物件
    imports: ["jsborn.core.channel"],

    initialize: function (options) {
        //讓此物件加入channel-01
        JSB.core.channel.join('channel-01', this, function (e, data) {
            console.log("i am org.jsborn.a :get channel-01 message!",data);
        });

    }

});

JSB.cls("org.jsborn.b", {
    //載入channel物件
    imports: ["jsborn.core.channel"],
    
    initialize: function (options) {
        JSB.core.channel.join('channel-01', this, function (e, data) {
            console.log("i am org.jsborn.b :get channel-01 message!", data);
        });
    }

});

JSB.cls("org.jsborn.c", {
    //載入channel物件
    imports: ["jsborn.core.channel"],

    initialize: function (options) {
        //傳送資料給在channel-01的物件
        JSB.core.channel.send('channel-01', 'SEND_DATA');

        //讓此物件加入channel-02
        JSB.core.channel.join('channel-02', this, function (e, data) {
            console.log("i am org.jsborn.c :get channel-02 message!", data);
        });
    }

});
var _ns_a = JSB.create("org.jsborn.a");
var _ns_b = JSB.create("org.jsborn.b");
var _ns_c = JSB.create("org.jsborn.c");
//傳送資料給在channel-02的物件
JSB.core.channel.send('channel-02','YOUR_DATA');
i am org.jsborn.a :get channel-01 message!
i am org.jsborn.b :get channel-01 message!
i am org.jsborn.c :get channel-02 message!

關於Channel

Channel 還有很多好用的功能,你可以到此查看 Channel物件 的API文件


Model物件 jsborn.core.model

Model 提供了簡單的資料偵測,例如:比對資料前後差異(目前Model還在擴充中...)

以下範例:使用兩個物件比對之間的差異

編輯範例
JSB.cls("org.jsborn.d", {
    //載入channel物件
    imports: ["jsborn.core.model"],

    initialize: function (options) {

        var _obj_original = {
            "name": "original",
                "data": {
                "age": 20
            }
        }
        //複製_obj_original
        var _obj_change = jQuery.extend(true, {}, _obj_original, "modify");
        //修改資料
        _obj_change.name = "change";
        _obj_change.data.age = "21";
        //使用model檢查改變過什麼
        var _obj_diff = JSB.core.model.getObjtDiff(_obj_original, _obj_change, "modify");
        //如果有改變
        if (!jQuery.isEmptyObject(_obj_diff)) {
            //使用model取得改變的數值
            var _str_name = JSB.core.model.getObjKey(_obj_diff, "name");
            var _str_age = JSB.core.model.getObjKey(_obj_diff, "data.age");

            console.log("name:" + _str_name);

            console.log("age:" + _str_age);

        }

    }

});
var _ns_d = JSB.create("org.jsborn.d");
name:change
age:21

關於Model

如果物件需要監聽物件資料改變Model,建議使用jsborn.plugin.model,關於jsborn.plugin.model的功能可查看 Model插件

關於Model的功能,你可以到此查看 Model物件 的API文件

擴充物件是指對物件/class進行擴充,目前JSBorn提供兩個內建的插件:ControllerModel

JSBorn內建的插件擴充預設都不會載入,只有您需要使用到時才會載入

若要預設載入某些插件,可以查看 JSB.setConfig

若需要自行開發插件,你可以到此查看 開發者 文件


Controller插件 jsborn.plugin.controller

Controller 插件會擴充JSBorn原有的物件,讓物件更容易的與HTML溝通,只要透過HTML attribute 即可自動對DOM註冊事件,資料改變刷新等功能,而不需要每次對HTML綁定事件。

Controller 依賴 jsborn.core.modeljsborn.plugin.model

範例(一):自動綁定事件

編輯範例
...
<div id="controller-test">
	<div jsb-event="click:_click_cb">
		please click me!
	</div>
	<input jsb-event="keyup:_keyup_cb"/>
</div>
...
JSB.cls("org.jsborn.controller", {
	//載入controller插件
	plugins:["jsborn.plugin.controller"],
	
	initialize: function(options) {

		var dd = this;
		//對物件鎖定要控制的DOM
		this.setRoot("#controller-test");
		//一旦設定Root後即可對DOM自動綁定事件
		this.registerEvent();

	},
	//這裡的"_click_cb"是對應HTML裡的jsb-event="click:_click_cb"
	_click_cb:function(){

		alert("_click_cb");
		
	},

	_keyup_cb:function(e){

		alert("_keyup_cb:"+e.keyCode);

	}

})

setRoot : 對物件鎖定要控制的DOM

registerEvent :會自動搜尋ROOT ID DOM的 jsb-eventclick 對應jQuery event 而 _click_cb 則是 event callback

var _ns_a = JSB.create("org.jsborn.controller");
點擊"please click me!" or 在Input輸入文字 即可測試

範例(二):整合上述例子,當物件資料改變時會更新HTML

編輯範例
...

<div id="controller-test">
    <div>your key in result : <span jsb-data="key:name" ></span>
    </div>
    <input jsb-event="keyup:_keyup_cb" />
</div>
<div id="controller-test2">
    <div>your key in result : <span jsb-data="key:name" ></span>
    </div>
    <input jsb-event="keyup:_keyup_cb" />
</div>

...

JSB.cls("org.jsborn.controller", {
    //載入controller插件
    plugins: ["jsborn.plugin.controller"],

    initialize: function (id) {

        this.setRoot(id);

        this.addModel("key", {
            name: ""
        });        

        this.registerEvent();
        
        this.registerData();
        
    },

    _keyup_cb: function (e) {
        //因為回傳的是jQuery物件,所以可以從裡面取回此物件的作用域
        var me = e.data.scope;
        
        me.setModel("key", {
            name: "id" + me.getRoot() + "-" + e.keyCode
        });

    }

});

		//傳入不同的ID
JSB.create("org.jsborn.controller",'#controller-test');
JSB.create("org.jsborn.controller",'#controller-test2');
	
在input輸入即可看到效果!

getRoot : 取得物件setRoot時的ID

registerData :會自動搜尋ROOT ID DOM 的 jsb-datakey

addModel :新增名為key的資料

setModel :更新名為key的資料

範例(三):在HTML內自動註冊物件,這有點抽象,建議看DEMO

編輯範例
...
<div id="controller-test">
    <div jsb-event="click:_click_cb">please click me!</div>
    <div jsb-cls="org.jsborn.controller.node">
        <div jsb-event="click:_node_cb">please click node!</div>
    </div>
</div>
...
JSB.cls("org.jsborn.controller", {

    plugins: ["jsborn.plugin.controller"],

    initialize: function (options) {

        this.setRoot("#controller-test");
        //監聽如果註冊了class時的callback
        this.addListener("controller-create", function (e,scope,element) {
            //這個scope指的是 org.jsborn.controller.node
            scope.setRoot(element);

            scope.registerEvent();

        });

        this.registerEvent();

        this.registerClass();

    },

    _click_cb: function () {

        alert("_click_cb");

    }

})

JSB.cls("org.jsborn.controller.node", {
    
    plugins: ["jsborn.plugin.controller"],
    
    initialize: function (options) {
    },
    
    _node_cb: function (e) {

        var scope = e.data.scope;

        alert("_node_cb");

    }
    
})

JSB.create("org.jsborn.controller");

registerClass :會自動搜尋ROOT ID DOM 的 jsb-cls, 然後自動建立Class。

關於Controller

Controller 還有很多好用的功能,你可以到此查看 Controller插件 的API文件


Model插件 jsborn.plugin.model

Model 插件會擴充JSBorn原有的物件,讓物件對設定的資料監聽事件,例如:資料改變時收到通知等功能。

Model 依賴 jsborn.core.model

範例(一):監聽資料改變事件,並用jQuery改變HTML

編輯範例
...
<h3>name:<span id="txt">hello</span></h3>

<button id="btn" class="btn btn-block btn-info">change name to helloworld!</button>
<button id="btn2" class="btn btn-block btn-warning">change name to hello</button>

<h3>data add:<span id="txt-data"></span></h3>

<button id="btn3" class="btn btn-block btn-warning">add data</button>

<h3>data del:<span id="txt-del"></span></h3>

<button id="btn4" class="btn btn-block btn-warning">del data</button>
...
JSB.cls("org.jsborn.model", {
    
    plugins: ["jsborn.plugin.model"],

    initialize: function (options) {

        jQuery('#btn').on('click', {
            scope: this
        }, this._click_cb);

        jQuery('#btn2').on('click', {
            scope: this
        }, this._click_cb2);

        jQuery('#btn3').on('click', {
            scope: this
        }, this._click_cb3);

        jQuery('#btn4').on('click', {
            scope: this
        }, this._click_cb4);

        this.addModel("name-data", {
            name: 'hello'
        }).addListener("model-modify", this._modify, this);

        this.getModel("name-data").addListener("model-add", this._add, this);

        this.getModel("name-data").addListener("model-del", this._del, this);
    },

    _click_cb: function (e) {
        var scope = e.data.scope;
        var _obj_data = scope.getModel("name-data").getData();
        _obj_data.name = 'hellowrold!';
        scope.setModel("name-data", _obj_data);
    },

    _click_cb2: function (e) {
        var scope = e.data.scope;
        var _obj_data = scope.getModel("name-data").getData();
        _obj_data.name = 'hello';
        scope.setModel("name-data", _obj_data);
    },
    _click_cb3: function (e) {
        var scope = e.data.scope;
        var _obj_data = scope.getModel("name-data").getData();
        _obj_data.age = 15;
        scope.setModel("name-data", _obj_data);
    },
    _click_cb4: function (e) {
        var scope = e.data.scope;
        var _obj_data = scope.getModel("name-data").getData();
        delete _obj_data.name;
        scope.setModel("name-data", _obj_data);
    },
    _add: function (e,scope,data) {
        console.log("add", data);
        for (key in data) {
            jQuery('#txt-data').html(key + ":" + data[key]);
        }
    },
    _del: function (e,scope,data) {
        console.log("delete", data);
        for (key in data) {
            jQuery('#txt-del').html(key);
        }
    },
    _modify: function (e,scope,data) {
        console.log("_modify", data);
        jQuery('#txt').html(data.name);
    }

});
JSB.create("org.jsborn.model");
打開console,並且點擊按鈕即可測試

關於Model

Model 還有很多好用的功能,你可以到此查看 Model插件 的API文件