構建多頁的先後分離web項目(alpaca-spa的視圖用法)

本文用來介紹使用alpaca-spa構建多頁的先後分離項目的js實現。javascript

關於alpaca-spa的其餘功能,請參考官方文檔css

Alpaca-spa.js是一款輕量的前端JS框架,提供前端路由功能,前端視圖渲染功能,前端頁面嵌套功能。目的是用來提升web項目的開發效率,先後端分離開發,同時使前端代碼結構更加整潔。 Alpaca-spa.js 區別於其餘框架的主要特色是輕巧靈活移動端、PC端都適用大小項目都適用,並且學習成本低, 框架沒有複雜的概念與特性,不依賴開發環境(如node.js等),都是最基本的JavaScript語法,也就是說讀者只要有JavaScript語言基礎,就能夠很快學會使用 Alpaca-spa.js框架用來構建前端頁面。html

官方文檔:http://www.tkc8.com前端

本文示例代碼(oschina):https://gitee.com/cc-sponge/alpaca-spa-2.0java

示例代碼(github):https://github.com/big-sponge/Alpaca-Spa-2.0node

完整的先後分離項目示例:http://full.tkc8.comjquery

1 簡介

視圖功能是Alpaca-Spa.js的核心功能,主要解決前端JavaScript實現頁面嵌套,頁面數據渲染,頁面局部渲染等功能。 使用alpaca-spa的View功能,能夠輕鬆構建多頁面先後分離結構,尤爲是在開發後臺功能時,很是實用。 固然,使用alpaca-spa開發移動端h5網站,單頁面結構網站也是很是不錯的選擇。 使用視圖功能須要配置web服務器,例如apache, nginx,node等。 這裏使用apache舉例,假設你的網站根目錄位於:nginx

C:\www\

固然你能夠配置apache的虛擬主機,將網站的根目錄放在任意你喜歡的地方。git

若是大家項目的先後端在同一個域名下面,也就是網站根目錄先後端用的是同一個,那前端的代碼通常不會直接放在根木目下面, 在根目錄下面創建一個叫 alpaca-spa或者叫其餘名字的目錄(只要不與後端路由衝突既可),例如將前端代碼放到 alpaca-spa目錄下面github

一個簡單的目錄結構以下:

--C:\www\alpaca-spa\
  --main\
    --controller\
       index.js
    --view\
       --index\
            index.html
            index-2.html
            index-3.html
       --layout\
            --part\
               leftMenu.html
            layout.html
    main.js
   index.html
1. 示例中的www是項目的根目錄,應該將web服務器的根目錄設置爲此目錄。

2. alpaca-spa是前端項目的目錄,目錄下面有1個子目錄,1個html文件。
   main         main目錄用來存放當前項目中全部main模塊的文件。能夠建立多個模塊。
   index.html   index.html用來作當前項目的入口文件

3.index目錄裏面有兩個目錄controller,view,一個js文件
   controller   用來存放main模塊的控制器的js代碼。裏面有一個控制器js文件,index.js
   view         用來存放main模塊的視圖部分的js代碼。
                示例中view目錄裏面有一個子目錄index,用於存放index控制器中相關的模板,
                本示例中,有三個模板:index.html,index2.html,index3.html
                還有一個子目錄layout,用於存放公共的佈局信息,
                layout目錄中的layout.html是默認的佈局模板文件
                layout目錄中的還有一個子目錄part,用來存放頁面中其餘公共區域,例如菜單等
   main.js      main.js是main模塊的模塊級別的js代碼。
                推薦在這個文件裏面作模塊的定義,例如:Alpaca.MainModule = {};

示例訪問地址: http://www1.tkc8.com/alpaca-spa/index.html

2 使用View

瞭解完上面的目錄結構以後,咱們來學習使用Alpaca.View()方法,參看下面的示例。

alpaca-spa/index.html 文件中的內容:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>alpaca-spa.2.1</title>

    <!-- 簡單調整一下樣式 -->
    <link  type="text/css" href="common/css/style.css">

    <!-- 引入alpaca-spa.js-->
    <script type='text/javascript' src='http://spa.tkc8.com/common/js/jquery-2.1.4.min.js'></script>
    <script type="text/javascript" src="http://spa.tkc8.com/common/js/alpaca-spa-2.1.js"></script>

    <!-- 引入main模塊main.js-->
    <script type="text/javascript" src="main/main.js"></script>
    <!-- 引入main模塊下index控制器index.js-->
    <script type="text/javascript" src="main/controller/index.js"></script>

    <!-- 運行 alpaca-spa Js-->
    <script>
        $(function () {
            /* 配置baseUrl。
             * 因爲alpaca請求視圖模版是從根目錄進行尋址,
             * 當前項目不在根目錄,在根目錄的下一級目錄中
             * */
            Alpaca.Config.baseUrl = "/alpaca-spa/";

            /*啓動alpaca,指定默認路由 #/main/index/index */
            Alpaca.run("#/main/index/index");
        });
    </script>
</head>
<body>
</body>
</html>

alpaca-spa/main/main.js 文件中的內容:

/* 1 定義Index模塊 */
Alpaca.MainModule = {};

alpaca-spa/main/controller/index.js 文件中的內容:

/* 1 定義Main模塊中的Index控制器 */
Alpaca.MainModule.IndexController = {
    //index動做,建立一個視圖index
    indexAction: function () {
        //視圖默認渲染到#content位置,能夠經過參數中傳遞to字段改變渲染位置
        //視圖模板默認位於index/view/index/index.html,能夠經過參數中傳遞template字段改變模塊路徑
        //即:默認模板位置爲:[模塊名]/view/[控制器名]/[動做名].html
        var view = new Alpaca.View({data:{desc:'我是一條數據,在controller中傳遞到view視圖模版裏面!'}});

        //layout 佈局視圖
        var layout = new Alpaca.Layout();

        //part 部件視圖,默認路由位於view/layout/part中,文件名默認與name屬性相同
        //part 的默認渲染位置與其name屬性相同,固然也能夠經過to屬性指定
        var part = new Alpaca.Part({name: 'leftMenu'});

        //將part添加到layout中,part的默認渲染位置與其name屬性相同,也能夠經過to屬性指定
        layout.addChild(part);

        //設置視圖的layout
        view.setLayout(layout);

        //在view中,向layout中傳遞數據
        view.setLayoutData({'layoutData': 666});

        //在view中,向part中傳遞數據
        view.setPartData({leftMenu: {'partData': 888}});

        return view;
    },

    //index2動做,建立視圖index2
    index2Action: function () {
        var view   = new Alpaca.View();
        var layout = new Alpaca.Layout();
        var part   = new Alpaca.Part({name: 'leftMenu'});
        layout.addChild(part);
        view.setLayout(layout);
        view.setLayoutData({'layoutData': '666 - 2'});
        view.setPartData({leftMenu: {'partData': '888 - 2'}});
        return view;
    },

    //index3動做,建立視圖index3
    index3Action: function () {
        var view   = new Alpaca.View();
        var layout = new Alpaca.Layout();
        var part   = new Alpaca.Part({name: 'leftMenu'});
        layout.addChild(part);
        view.setLayout(layout);
        view.setLayoutData({'layoutData': '666 -- 3'});
        view.setPartData({leftMenu: {'partData': '888 -- 3'}});
        return view;
    },
};

alpaca-spa/main/index/view/index.html 文件中的內容:

<div> 我是內容區域:當前顯示的是index.html裏面的內容 </div>
<h5>我有一條數據:</h5>
{{= it.desc }}

alpaca-spa/main/index/view/index2.html 文件中的內容:

<div> 我是內容區域:當前顯示的是index2.html裏面的內容 </div>

alpaca-spa/main/index/view/index3.html 文件中的內容:

<div> 我是內容區域:當前顯示的是index3.html裏面的內容 </div>

在瀏覽器中訪問: http://www1.tkc8.com/alpaca-spa/index.html

點擊按鈕,能夠看到內容區域切換到對應的頁面了,總體佈局layout、菜單leftMenu除了數據其餘的都沒有變化,

上面的示例中,咱們建立了Main模塊,index控制器,index動做,而且在indexAction中經過Alpaca.View()方法建立了一個視圖,運行結果是視圖模板中的內容被渲染到了頁面的#content位置中。這就是Alpaca.View()的用途。

Alpaca.View()方法

Alpaca.View(option) 是一個用來建立視圖頁面的方法,接受一個對象參數option,參數option中能夠包含如下字段:

  • option.data

  數據對象,爲渲染模板提供數據

  例如:Alpaca.View({data:{name:'Alpaca-spa'}})

  • option.to

  設置被渲染位置,默認位置是#content

  例如:Alpaca.View({data:{name:'Alpaca-spa'},to:'#divId'})

  • option.template

  指定渲染的模板文件。默認是所屬模塊view目錄下所屬controller同名目錄下action同名的.html文件,即:默認模板位置爲:[模塊名]/view/[控制器名]/[動做名].html

  若是須要改變視圖模板,只須要這樣寫便可:template:'index2',這樣就會使用同名controller下的index2.html做爲模板。

  這是由於函數內部自動格式化了該參數,若是不想使用自動格式化功能,請使用notFormat參數,設置notFormat:true 便可。

  例如:Alpaca.View({data:{name:'Alpaca-spa'},to:'body',template:'index2'})

  • option.notFormat (通常不用,不推薦使用,能夠跳過不看)

  默認爲false,表示系統會自動格式化template參數,若是設置爲true,以下例,視圖將使用根目錄下的index-test.html文件做爲視圖模板。 Alpaca.View(template:'/index-test.html',notFormat:true})

3 使用Layout和Part

實際的web項目開發中,大部分頁面都是有結構的,好比整體的佈局,公用的菜單、頁頭、頁尾等。Alpaca-sap.js使用layout,part來解決這類問題。

繼續上面介紹View的示例:

觀察alpaca-spa/main/controller/index.js 文件中的內容:

indexAction: function () {
        //視圖默認渲染到#content位置,能夠經過參數中傳遞to字段改變渲染位置
        //視圖模板默認位於index/view/index/index.html,能夠經過參數中傳遞template字段改變模塊路徑
        //即:默認模板位置爲:[模塊名]/view/[控制器名]/[動做名].html
        var view = new Alpaca.View({data:{desc:'我是一條數據,在controller中傳遞到view視圖模版裏面!'}});

        //layout 佈局視圖
        var layout = new Alpaca.Layout();

        //part 部件視圖,默認路由位於view/layout/part中,文件名默認與name屬性相同
        //part 的默認渲染位置與其name屬性相同,固然也能夠經過to屬性指定
        var part = new Alpaca.Part({name: 'leftMenu'});

        //將part添加到layout中,part的默認渲染位置與其name屬性相同,也能夠經過to屬性指定
        layout.addChild(part);

        //設置視圖的layout
        view.setLayout(layout);

        //在view中,向layout中傳遞數據
        view.setLayoutData({'layoutData': 666});

        //在view中,向part中傳遞數據
        view.setPartData({leftMenu: {'partData': 888}});

        return view;
    },

以及:alpaca-spa/main/view/layout/layout.html 文件中的內容爲:

<style>
    .layout-css {
        border: 1px solid green;
        padding: 20px;
    }

    #content, #leftMenu {
        border: 1px dashed green;
    }

    #content {
        padding: 20px;
    }
</style>

<div class="layout-css">

    <h2> 我是layout! 數據【{{=it.layoutData}}】是在控制器中傳遞給個人。</h2>

    <h5>左邊菜單:</h5>
    <div id="leftMenu"></div>

    <h5>頁面內容區域:</h5>
    <div id="content"></div>

</div>

alpaca-spa/main/view/layout/part/leftMenu.html 文件中的內容爲:

<style>
    .lm-css {
        padding: 20px;;
    }
</style>

<div class="lm-css">
    <h3>我是左邊的菜單,請把我放到左面! 數據【{{=it.partData}}】是在控制器中傳遞給個人。</h3>
    <h6>點下面的鏈接能夠切換其餘頁面</h6>

    <button type="button" onclick="toIndex1()"> 頁面Index1</button>
    <button type="button" onclick="toIndex2()"> 頁面Index2</button>
    <button type="button" onclick="toIndex3()"> 頁面Index3</button>
</div>


<script>
    /*必須注意 在模版中寫js,註釋不能夠用「//」*/
    var toIndex1 = function () {
        Alpaca.to('#/main/index/index');
    };
    var toIndex2 = function () {
        Alpaca.to('#/main/index/index2');
    };
    var toIndex3 = function () {
        Alpaca.to('#/main/index/index3');
    }
</script>

上面的示例演示瞭如何使用 layout、part來渲染複雜頁面。

Alpaca.Layout()方法

Alpaca.Layout(option) 是用來建立一個layout佈局的視圖對象的方法,接受一個對象參數option,參數option中能夠包含如下字段:

  • option.data

  數據對象,爲渲染模板提供數據

  例如:Alpaca.Layout({data:{name:'Alpaca-spa'}})

  • option.to

  設置被渲染位置,默認位置是body

  例如:Alpaca.Layout({data:{name:'Alpaca-spa'},to:'#divId'})

  • option.name

  指定layout的名字。默認爲layout

  layout默認的模板路徑是所屬模塊view目錄下layout目錄下的layout.html文件

  經過name字段能夠修改模板的路徑爲:所屬模塊view目錄下layout目錄下與name同名的html文件

  例如:Alpaca.Layout({data:{name:'Alpaca-spa'},to:'body',name:'layout2'})

Alpaca.Part()方法

Alpaca.Part(option) 是用來建立一個part佈局的視圖對象的方法,接受一個對象參數option,參數option中能夠包含如下字段:

  • option.data

  數據對象,爲渲染模板提供數據

  例如:Alpaca.Part({data:{name:'Alpaca-spa'}})

  • option.name

  指定Part的名字。

  Part默認的模板路徑是所屬模塊view\layout\part目錄下與其name同名的html文件

  Part默認的渲染位置是id與其name同名的元素

  經過name字段能夠達到指定他的視圖模板路徑,以及渲染位置的效果,例如,

  例如:Alpaca.Part({data:{name:'Alpaca-spa'},name:'top'})

  • option.to

  設置被渲染位置,默認位置是id與其name同名的元素

  例如:Alpaca.Part({data:{name:'Alpaca-spa'},to:'#divId'})

4. 如何改變layout、view的默認渲染位置

  • 一、layout默認渲染位置是 <body></body>位置,

經過設置Alpaca.ViewModel.DefaultLayoutCaptureTo = "body"; 能夠全局改變layout的默認渲染位置

若是隻修改當前視圖的渲染位置,有兩種方法:

var layout = new Alpaca.Layout({to:'body'}});

或者

var layout = new Alpaca.Layout();
layout.setCaptureTo('.layout-area');
  • 二、view默認渲染位置是 <div id="content"> </div> 位置,

經過設置Alpaca.ViewModel.DefaultViewCaptureTo = "body";能夠全局改變view的默認渲染位置

若是隻修改當前視圖的渲染位置,有兩種方法:

var view = new Alpaca.View({to:'#content'}});

或者

var view = new Alpaca.View();
view.setCaptureTo('.content-area');

layout、view的默認渲染位置很是重要,一個路由執行後,url中的hash是否改變,就依據layout、view的默認位置決定。而hash是否改變,會影響刷新點擊按鈕的結果。

  • 一、若是當前view沒有使用layout,則view的CaptureTo等於DefaultLayoutCaptureTo時,hash會改變
  • 二、若是使用了layout,則layout的CaptureTo等於DefaultLayoutCaptureTo時,hash會改變

5 ready()方法

視圖渲染完畢後會執行view.ready()方法,例如

var view = new Alpaca.View()

//視圖渲染完成後執行ready方法。
view.ready(function () {
	console.log('視圖渲染完成了...');
})

return view;

6 自定義顯示效果

經過設置view.show方法能夠自定義視圖顯示效果,例如:

var view = new Alpaca.View();

//自定義視圖渲染效果爲閃入效果。
//注意:在自定義視圖顯示效果時,須要調用onLoad事件,來觸發執行ready函數。
view.show = function (to, html) {
    var that = this;
    $(to).fadeOut("fast", function () {
        $(to).html(html);
        $(to).fadeIn("fast", function () {
            that.onLoad();
        });
    });
};

return view;

上面面示例代碼,實現了視圖渲染時的閃入效果。

7 init()與release()方法

若是在控制器中定義了init()方法,那麼在執行當前控制器的全部action方法前都會執行init()方法。若是在控制器中定義了release()方法,那麼在執行完成當前控制器的全部action方法以後,都會執行release()方法,

模塊中也能夠定義init()、release()方法。

參考示例:

/* 定義Index模塊中的TestController */
Alpaca.IndexModule.TestController = {

	//init方法,當前控制下的全部動做在執行前,都會執行init方法
	init:function(){
		console.log('執行action以前,執行init()方法');
	},

	//release方法,當前控制下的全部動做在執行前,都會執行release方法
	release:function(){
		console.log('執行action以後,執行release)方法');
	},
};

8. 關於hash什麼時候被改變

1:若是未使用layout,則view的CaptureTo等於DefaultLayoutCaptureTo
2:若是使用了layout,則layout的CaptureTo等於DefaultLayoutCaptureTo
相關文章
相關標籤/搜索