正如它的名字,模塊用於amaplejs單頁應用的頁面分割,全部的跳轉更新和代碼編寫都是以模塊爲單位的。javascript
一個模塊由<module>
標籤對包含,內部分爲template模板、JavaScript和css三部分,像這樣:php
<module> <template> <!-- 編寫模塊的html模板 --> <span>hello amaplejs,page index</span> <a href="/about?from=index">direct to page about</a> </template> <script> // 編寫模塊JavaScript代碼 // 在一個模塊的JavaScript中,am爲自動注入對象,你不需引入它,即便是在webpack環境下 // 這裏一般使用new am.Module()建立一個amaple模塊對象,它將會在構造函數中處理模板內容和模板樣式等一系列的初始化工做 new am.Module (); </script> <style scoped> /* 編寫模塊樣式 */ span { font-size: 20px; } </style> </module>
大多數狀況下咱們可能更但願讓一個模塊中的css樣式只做用當前的html模板,這固然咱們也有所考慮,只需在<style>
中添加scoped
屬性就會自動限制它的做用範圍了,就是如此簡單。但若是<style>
不帶scoped
屬性時將不會只做用到當前的html模板內。css
當咱們在編寫一個模塊的JavaScript時一般使用am.Module
類建立一個amaple模塊對象,它將會在構造函數中進行一系列的初始化工做,而一個模塊的生命週期函數將會在初始化的不一樣階段,或模塊數據改變時自動觸發,它們共分爲5個階段,具體以下:html
init
:模塊初始化時觸發,它將要求你在定義時返回<template>
模板中所使用的狀態數據關於狀態數據的內容將在「模板指令與狀態數據(state)」中講解
mounted
:解析模板並掛載狀態數據時觸發,你能夠在這裏處理一些模塊的後續操做,如爲此模塊請求網絡數據並更新到模板中等。queryUpdated
:模塊更新時部分不需被替換的模塊,檢測到GET或POST參數變化(增長、移除或修改參數)時觸發,如全部頁面的header部分老是不變,此時它將不會被替換。paramUpdated
:模塊更新時部分不需被替換的模塊,檢測到param
參數變化(增長、移除或修改參數)時觸發,只有設置了路由通配符的模塊纔有param
參數。關於路由通配符的內容咱們將會在《路由配置》中詳細講解
unmount
:在更新模塊時被替換的模塊將會觸發。你能夠這樣設置一個模塊的生命週期函數:java
<template>...</template> <script> new am.Module ( { init : function () { // 返回一個包含狀態數據的對象,這些狀態數據做用是解析掛載模板 return {}; }, mounted : function () {}, queryUpdated : function () {}, paramUpdated : function () {}, unmount : function () {} } ); </script>
【注意】生命週期函數內的this
指向am.Module
對象,若是它們使用ES6的箭頭函數(Arrow function)會致使函數內this
指針指向不正確而出錯。
和普通頁面同樣,模塊跳轉與表單提交都會改變url,在host與port都相同的狀況下都會觸發模塊更新,不然將進行頁面刷新的普通跳轉。模塊匹配及更新看以下圖解:
webpack
在普通頁面的跳轉中,咱們使用<a>
標籤設置href
屬性進行跳轉,在amaplejs中也是如此,但不一樣的是,全部dom元素上設置了href
屬性後,點擊均可以觸發模塊更新,而且當href
後帶有get
參數時將會解析成鍵值對保存在am.Module
對象內:web
<a href="/about?from=index">direct to page about</a>
點擊此按鈕跳轉將會匹配到/module/about.html
模塊,而且about
模塊對象內的get
參數值爲{from: "index"}
。segmentfault
// about模塊內可以使用this.get對象的屬性值 new am.Module ( { init : function () { return { from: this.get.from }; } } );
amaplejs的表單提交與普通頁面的表單提交寫法也相同,在<form>
內編寫表單元素並設置action
屬性,它指定表單提交路的路徑:網絡
<template> <form action="account/register"> <input type="text" name="username" value="jim" /> <input type="password" name="pwd" value="jim001" /> <input type="text" value="10" /> </form> ... </template>
提交表單到account/register
後,服務端需返回一個路徑字符串,來告訴框架表單提交後跳轉的路徑,它可能像這樣:框架
<?php // 表單數據的處理 // ... echo "/submit/success"; ?>
表單提交後將會使用服務端返回的/submit/success
路徑進行模塊的更新跳轉,這樣就完成了一個表單提交,此時/submit/success
路徑所匹配的模塊中會自動生成post
參數對象{ username: "jim" }
(表單元素設置了name
屬性,且type
不爲password
的值纔會在this.post
中建立):
new am.Module ( { init : function () { return { this.username : this.post.username }; } // ... } );
爲了實現多個模塊間的跳轉,你能夠繼續建立一個module/about.html
模塊文件,內容與index.html
幾乎相同,像這樣:
<module> <template> <span>hello amaplejs,page about</span> <a href="/index?from=about">direct to page index</a> </template> <script> new am.Module (); </script> <style scoped> span { font-size: 20px; } </style> </module>
當一個頁面需設置二級菜單時,咱們可能但願在一個模塊中嵌套一個模塊節點,而這在amaplejs中也是支持的,你只需在一個模塊的<template>
模板內繼續使用:module
屬性定義模塊節點,如:
<template> <span>hello amaplejs,page index</span> <a href="/about?from=index">direct to page about</a> <div :module></div> </template>
這樣就嵌套了一個不具名的模塊節點,你可能會問怎麼能夠定義兩個不具名的模塊節點呢,這是由於amaplejs可支持你設置無限層級的嵌套模塊,就像html的元素嵌套同樣,而且不一樣層級模塊節點的命名空間(namespace)是相互獨立的,但相同層級只能有一個不具名的模塊節點,且不能出現名稱相同的模塊節點(其實不具名的模塊節點的名稱默認是「default」)。
【對模塊層級的理解】模塊層級與dom元素層級無關,需以模塊爲單位節點做爲層級參考標準,不一樣模塊內定義的嵌套模塊爲不一樣層級,而同一個模塊內定義的嵌套模塊不論位置如何都屬於同一層級。
定義嵌套模塊節點後,咱們也需爲它配置路由映射,指定嵌套模塊節點在不一樣url下應該匹配哪些模塊:
am.startRouter( { routes : function ( router ) { // 使用route函數的第三個參數設置嵌套模塊節點的路由映射 router.module ().route ( "/", "module/index", function ( childRouter ) { // 此回調函數將接收一個childRouter參數 // 不一樣層的命名空間是獨立的,因此調用router.module函數指定的是嵌套層的模塊節點 childRouter.module ().route ( "subpage", "module/index/sub_page" ); // 它將首先匹配「/」,而後繼續匹配嵌套模塊「subpage」 } ) .route ( "/about", "module/about" ); }, // ... } );
嵌套模塊節點與上一層模塊節點的關係爲父子模塊,它們常常須要進行通訊,如父模塊下發數據到子模塊中,或父模塊訪問子模塊的數據,此時你能夠這樣作:
// 在子模塊中經過parent屬性來獲取父模塊對象 new am.Module ( { init : function () { // this.parent爲父模塊對象,當一個模塊爲最頂層模塊時,它的parent屬性將爲null return { btnText : this.parent.state.text }; } // ... } );
在父模塊中不能直接訪問到子模塊對象,但可經過子模塊主動傳值的方式讓父模塊獲取到子模塊的數據,就像咱們的代碼做用域,外層做用域不能直接獲取內層做用域的值,但可經過內層做用域爲外層做用域的變量賦值來訪問。在子模塊中經過parent
屬性來獲取父模塊對象,而後調用父模塊中定義的模塊函數並傳入相應的值便可主動傳值到父模塊了。
模塊函數將在《模板指令與狀態數據》中講解
繼續學習下一節:【AmapleJS教程】3. 模板指令與狀態數據(state)
也可回顧上一節:【AmapleJS教程】1. 啓動路由