今天要介紹的是初級的觀念,是關於Application Layout的話題,所謂的Application Layout就是你在撰寫程式的時候,如何決定你程式碼的風格,讓它具備有相當的易讀性。這樣做的好處,一來是在團隊裡面如果程式碼風格固定,別人要接手或支援你的專案會比較容易。二來如果以後你要修改程式,也必較容易。以我來說,由於每天開發實在很大,一周前寫的程式自己都越覺得很陌生。好啦,廢話不多說,至接近入正題。
一開始我們些略過JavaScript兩種建立物件的方法,我先把大概介紹一下,但是這篇文章不會談論到這個部分。
方法一是:
- var MyObject = function(){
- /*Your Code Here*/
- };
var MyObject = function(){ /*Your Code Here*/ };
方法二是:
- var MyObject = function(){
- return{
- /*Your Code Here*/
- }
- }();
var MyObject = function(){ return{ /*Your Code Here*/ } }();
好,今天我們介紹的Application Layout是許多Javascript設計師常用的架構,當然每個人都又自己的偏好。不過我觀察到一個趨勢,今天介紹的架構是最受許多人歡迎的。
- MyObject = function() {
- // private variables : 私有屬性或稱為區域變數
- // private functions : 私有方法或稱為區域方法
- // public space
- return {
- // public properties, e.g. strings to translate : 公有屬性或稱為公開變數
- // public methods : 公有方法或稱為公開方法
- init: function() {
- alert('Application successfully initialized');
- }
- };
- }(); //
MyObject = function() { // private variables : 私有屬性或稱為區域變數 // private functions : 私有方法或稱為區域方法 // public space return { // public properties, e.g. strings to translate : 公有屬性或稱為公開變數 // public methods : 公有方法或稱為公開方法 init: function() { alert('Application successfully initialized'); } }; }(); //
上面一堆提到一堆公有/私有,公開/區域..等名詞都是翻譯的問題。我個人還是比較喜歡用英文來稱呼。
上面的架構已經把private 與public 的位置規劃出來了,所以如果把程式碼都放到正確的位置上,大致的架構應該如下
- MyObject = function() {
- var myFirstName='Jack';
- var myLastName='Slocum'; //sorry jack : )
- function getFirstName(){
- alert(myFirstName);
- }
- function getLastName(){
- alert(myLastName);
- }
- return {
- NickName1: 'Super Jack',
- NickName2: 'Good Futher Jack',
- init: function() {
- alert(this.NickName1); //在Public zone裡面的需要使用this.xxxx來存取變數
- alert(myFirstName); //在Public zone裡面的直接使用 xxx來存取 private zone裡面的變數
- },
- other : function(){
- alert(this.NickName2); //在Public zone裡面的需要使用this.xxxx來存取變數
- alert(myLastName); //在Public zone裡面的直接使用 xxx來存取 private zone裡面的變數
- } //注意結尾的,需要去除不然龜毛的IE會拒絕執行
- };
- }(); //
MyObject = function() { var myFirstName='Jack'; var myLastName='Slocum'; //sorry jack : ) function getFirstName(){ alert(myFirstName); } function getLastName(){ alert(myLastName); } return { NickName1: 'Super Jack', NickName2: 'Good Futher Jack', init: function() { alert(this.NickName1); //在Public zone裡面的需要使用this.xxxx來存取變數 alert(myFirstName); //在Public zone裡面的直接使用 xxx來存取 private zone裡面的變數 }, other : function(){ alert(this.NickName2); //在Public zone裡面的需要使用this.xxxx來存取變數 alert(myLastName); //在Public zone裡面的直接使用 xxx來存取 private zone裡面的變數 } //注意結尾的,需要去除不然龜毛的IE會拒絕執行 }; }(); //
有幾點重點要提供給新手注意,這也是我剛學習Javascipt會遇到的疑惑與困擾。
第一個是變數的宣告方式:
在Private zone的變數使用分號(;)隔開舉例如下:
- var 變數1;
- var 變數2;
var 變數1; var 變數2;
但是在Public zone裡面的變數要使用逗號(,)隔開(註:其實這是JSON寫法的變型)舉例如下:
- 變數1:變數1的值,
- 變數2:變數2的值 //注意結尾的逗點在IE無法通過檢查
變數1:變數1的值, 變數2:變數2的值 //注意結尾的逗點在IE無法通過檢查
第二個是function(或稱方法)的宣告方式:
在Private zone的使用方法如下:
- function fun1(){
- /*Your code HERE*/
- };
- function fun2(){
- /*Your code HERE*/
- };
function fun1(){ /*Your code HERE*/ }; function fun2(){ /*Your code HERE*/ };
在但是在Public zone的使用方法如下,(註:還這是JSON寫法的變型):
- fun1: function() {
- /*Your code HERE*/
- },
- fun2: function() {
- /*Your code HERE*/
- }
fun1: function() { /*Your code HERE*/ }, fun2: function() { /*Your code HERE*/ }
最後我們來改寫Ajax XML data 的範例。
原始的程式如下,他是在Ext.onReady()裡面處理全部的工作:
- /*
- * Ext JS Library 1.1.1
- * Copyright(c) 2006-2007, Ext JS, LLC.
- * licensing@extjs.com
- *
- * http://www.extjs.com/license
- */
- Ext.onReady(function(){
- // create the Data Store
- var ds = new Ext.data.Store({
- // load using HTTP
- proxy: new Ext.data.HttpProxy({url: 'sheldon.xml'}),
- // the return will be XML, so lets set up a reader
- reader: new Ext.data.XmlReader({
- // records will have an "Item" tag
- record: 'Item',
- id: 'ASIN',
- totalRecords: '@total'
- }, [
- // set up the fields mapping into the xml doc
- // The first needs mapping, the others are very basic
- {name: 'Author', mapping: 'ItemAttributes > Author'},
- 'Title', 'Manufacturer', 'ProductGroup'
- ])
- });
- var cm = new Ext.grid.ColumnModel([
- {header: "Author", width: 120, dataIndex: 'Author'},
- {header: "Title", width: 180, dataIndex: 'Title'},
- {header: "Manufacturer", width: 115, dataIndex: 'Manufacturer'},
- {header: "Product Group", width: 100, dataIndex: 'ProductGroup'}
- ]);
- cm.defaultSortable = true;
- // create the grid
- var grid = new Ext.grid.Grid('example-grid', {
- ds: ds,
- cm: cm
- });
- grid.render();
- ds.load();
- });
/* * Ext JS Library 1.1.1 * Copyright(c) 2006-2007, Ext JS, LLC. * licensing@extjs.com * * http://www.extjs.com/license */ Ext.onReady(function(){ // create the Data Store var ds = new Ext.data.Store({ // load using HTTP proxy: new Ext.data.HttpProxy({url: 'sheldon.xml'}), // the return will be XML, so lets set up a reader reader: new Ext.data.XmlReader({ // records will have an "Item" tag record: 'Item', id: 'ASIN', totalRecords: '@total' }, [ // set up the fields mapping into the xml doc // The first needs mapping, the others are very basic {name: 'Author', mapping: 'ItemAttributes > Author'}, 'Title', 'Manufacturer', 'ProductGroup' ]) }); var cm = new Ext.grid.ColumnModel([ {header: "Author", width: 120, dataIndex: 'Author'}, {header: "Title", width: 180, dataIndex: 'Title'}, {header: "Manufacturer", width: 115, dataIndex: 'Manufacturer'}, {header: "Product Group", width: 100, dataIndex: 'ProductGroup'} ]); cm.defaultSortable = true; // create the grid var grid = new Ext.grid.Grid('example-grid', { ds: ds, cm: cm }); grid.render(); ds.load(); });
我們可以把它改寫如下,在我的規劃裡面,我把ds,cm,sm分別放在Private的function裡面處理,當然您也可以自己規劃自己的架構。
- var MyGrid=function(){
- var sm;
- var ds;
- var cm;
- var grid;
- /**
- * 初始化 sm: RowSelectionModel
- */
- function bulide_sm(){
- sm = new Ext.grid.RowSelectionModel({singleSelect:true});
- }
- /**
- * 初始化ds: Datasource
- */
- function bulder_ds(){
- ds = new Ext.data.Store({
- // load using HTTP
- proxy: new Ext.data.HttpProxy({url: 'sheldon.xml'}),
- // the return will be XML, so lets set up a reader
- reader: new Ext.data.XmlReader({
- // records will have an "Item" tag
- record: 'Item',
- id: 'ASIN',
- totalRecords: '@total'
- }, [
- // set up the fields mapping into the xml doc
- // The first needs mapping, the others are very basic
- {name: 'Author', mapping: 'ItemAttributes > Author'},
- 'Title', 'Manufacturer', 'ProductGroup'
- ])
- });
- }
- /**
- * 初始化cm: ColumnModel
- */
- function bulder_cm(){
- cm = new Ext.grid.ColumnModel([
- {header: "Author", width: 120, dataIndex: 'Author'},
- {header: "Title", width: 180, dataIndex: 'Title'},
- {header: "Manufacturer", width: 115, dataIndex: 'Manufacturer'},
- {header: "Product Group", width: 100, dataIndex: 'ProductGroup'}
- ]);
- cm.defaultSortable = true;
- }
- return{
- init : function(){
- bulder_cm();
- bulide_sm();
- bulder_ds();
- this.init_grid(); //產生gird
- ds.load();
- },
- init_grid : function(){
- // create the grid
- grid = new Ext.grid.Grid('example-grid', {
- ds: ds,
- cm: cm,
- selModel:sm,
- enableColLock:false,
- loadMask: true
- });
- grid.render();
- }
- }
- }();
var MyGrid=function(){ var sm; var ds; var cm; var grid; /** * 初始化 sm: RowSelectionModel */ function bulide_sm(){ sm = new Ext.grid.RowSelectionModel({singleSelect:true}); } /** * 初始化ds: Datasource */ function bulder_ds(){ ds = new Ext.data.Store({ // load using HTTP proxy: new Ext.data.HttpProxy({url: 'sheldon.xml'}), // the return will be XML, so lets set up a reader reader: new Ext.data.XmlReader({ // records will have an "Item" tag record: 'Item', id: 'ASIN', totalRecords: '@total' }, [ // set up the fields mapping into the xml doc // The first needs mapping, the others are very basic {name: 'Author', mapping: 'ItemAttributes > Author'}, 'Title', 'Manufacturer', 'ProductGroup' ]) }); } /** * 初始化cm: ColumnModel */ function bulder_cm(){ cm = new Ext.grid.ColumnModel([ {header: "Author", width: 120, dataIndex: 'Author'}, {header: "Title", width: 180, dataIndex: 'Title'}, {header: "Manufacturer", width: 115, dataIndex: 'Manufacturer'}, {header: "Product Group", width: 100, dataIndex: 'ProductGroup'} ]); cm.defaultSortable = true; } return{ init : function(){ bulder_cm(); bulide_sm(); bulder_ds(); this.init_grid(); //產生gird ds.load(); }, init_grid : function(){ // create the grid grid = new Ext.grid.Grid('example-grid', { ds: ds, cm: cm, selModel:sm, enableColLock:false, loadMask: true }); grid.render(); } } }();
最後,我們使用 來載入們剛剛寫好的物件。
- Ext.onReady(XmlGrid.init,XmlGrid,true);
Ext.onReady(XmlGrid.init,XmlGrid,true);
這樣做也許有人會覺得多此一舉,但是到程式開發的後期,你一定會遇到更複雜的架構,好比說一個Ext.Gird跟Ext.form互動,結構化的好處是以後再Javasript的開發上,你能將一個個的物件獨立出來,方便後期的修改與模組化。
我以後會發表Grid與form同步的教學文章。那時您大概就會了使用這個Application Layout的好處了。