directive.js
初始化和注冊路由
director.js 的主要對象是Router對象,構造方法如下:
var router = new Router(routes); //routes為路由表
構造方法中傳入的routes參數是一個路由表對象,它是一個具有鍵值對結構的對象,路由允許多層的嵌套定義。
鍵值對的鍵對應URL中傳入的路徑,一般一個鍵對應按分隔符切割后的某一部分;而鍵值對的值則對應該路徑需要觸發的回調函數名,可以傳入一個或多個函數名,傳入多個函數名時請使用數組對象。一般來說,回調函數要在路由表對象使用前先聲明,否則js會報錯。
另外,回調函數除非特殊情況,一般不推薦使用匿名函數,請盡量先聲明后使用。
var routes = {
'/dog': bark,
'/cat': [meow, scratch]
};
var router = new Router(routes);
router.init(); //初始化
上面例子中,對應的URL分別為:#/dog 和 #/cat
路由的實時注冊
當我們在開發一些規模比較大的應用的時候,一般做不到一開始就將需要的路徑和它對應的回調函數都預先准備好。很多時候,我們都是在做到某一功能時,或者是開發一些獨立性比較強耦合度比較低的模塊時,才知道我們需要什么樣的路徑和回調函數。這個時候我們就需要實時注冊路由的功能了。
director.js 通過“on”方法,提供對即時注冊功能的支持,示例如下:
var router = new Router(routes).init();
router.on('/rabbit', function(){
//....
});
路由事件
//注冊
router.on('/rabbit', handler);
router.once('/dog', handler2);
路由事件生命周期:
-
on :當路由匹配成功后,需要執行的方法
-
before:在觸發“on”方法之前執行的方法
-
after:當離開當前注冊路徑時,需要執行的方法
-
once: 當前注冊路徑僅執行一次的方法
var routes = {
'/about/:id': {
before: function(id){ alert('directive to /home/about/'+id); },
on: function(id){ window.location = '/home/about/'+id; }
}
}
配置參數
director.js 通過配置一些可選項的參數從而提升Router對象的靈活性。而這些參數的設置需要通過router.configure()方法實現。
var router = new Router(routes).configure(options);
具體的配置參數有:
-
recurse:控制路由遞歸觸發方式的參數,可選值為"forward","backward"和"false",客戶端的默認值是"false",而服務端的默認值是"backward"
-
strict:當值為"false"時,路徑允許以"/"結尾(也可以是其他自定義的分隔符);默認值是"true",說明默認不允許路徑以"/"結尾
-
async:同步異步控制器,值為"ture","false",默認值為"false"
-
delimiter:路由分隔符,默認值為"/"
-
notfound:當路由方法router.dispatch()被調用時,沒有匹配到任何路由時觸發的方法
-
on:當路由方法router.dispatch()被調用時,任何一個路由匹配成功后都需要執行的方法;與上文路由事件中的“on”事件的區別類似於全局和局部的概念,路由表中僅針對當前注冊的路由;而configure方法中的"on"則針對全局的所有路由
-
before:當路由方法router.dispatch()被調用時,當任何一個路由匹配成功並在"on"執行之前需要執行的方法;與上文路由事件中的 “before” 事件的區別同上
僅在客戶端有效的參數: -
resource:用來進行回調函數綁定的基於字符串的對象。使用該參數能實現回調函數的延遲綁定(原詞是 "late-binding",后面有相關的詳細說明)
-
after:當給定的路徑不再是當前激活的路徑時觸發的方法,可以理解為離開當前路徑后觸發的方法;與上文路由事件中的 “after” 事件的區別同上
URL匹配
url參數捕獲和嵌套路由定義
//例如"#/about/5"中,5就是id參數的值
var router = Router({
'/about': {
'/:id':{
on: function(id){ console.log(id); }
}
}
});
director.js 支持利用正則表達式來匹配復雜的路由名稱
//當URL傳入'#/hello/world',則回調函數的who=world
var router = new Router({
'/hello': {
'/(\\w+)': {
on: function(who){ console.log(who); }
}
}
});
//當URL傳入'#/hello/world/johny/appleseed',則回調函數的a=johny,b=applesee
var router = Router({
'/hello': {
'/world/?([^\/]*)\/([^\/]*)/?': function (a, b) {
console.log(a, b);
}
}
});
路由的遞歸匹配
全局配置中的recurse參數決定了路徑在路由表中的命中方式以及命中順序。命中方式包括遞歸命中和精確命中;命中順序包括正序,反序和中斷。
當參數設定為“forward、backward”時,表明路由的命中方式是遞歸命中,並按照規定的順序命中,forward為正序,backward為反序。路由如果定義了多個路由片段,則它們對應的回調函數均可命中,也就是說一個路徑可以命中多個函數。
當沒有特別指定該參數的值時(即默認值"false"),則標明路由的命中方式為精確命中,需要完全匹配整個路徑后才可以命中,也就是說一個路徑只能命中一個函數。
當URL傳入"#/dog/angry"時,路由表注冊如下:
var routes = {
'/dog': {
'/angry': {
on: growl
},
on: bark
}
};
當沒有指定遞歸匹配的方式時,僅命中growl方法。
當指定遞歸匹配參數的值為backward時,首先命中growl方法,然后再命中bark方法,按照路徑的注冊順序反序命中。如下:
var router = Router(routes).configure({ recurse: 'backward' });
當指定遞歸匹配參數的值為forward時,首先命中bark方法,然后再命中growl方法,按照路徑的注冊順序正序命中。如下:
var router = Router(routes).configure({ recurse: 'forward' });
當指定了遞歸匹配參數后,如果命中的函數中使用了"return false;"的語句返回,則會中斷遞歸命中,直接返回。如下:
var routes = {
'/dog': {
'/angry': {
on: function() { return false; }
},
on: bark
}
};
var router = Router(routes).configure({ recurse: 'backward' });
無中斷時,首先會命中angry下的方法,然后命中bark方法;但是在使用return false語句之后,執行完angry命中的方法后將不再遞歸命中別的方法(bark)。
資源參數
全局配置中的resource參數僅在客戶端應用中可用,它是一個文本對象,其中的文本屬性值主要用來定義路由匹配命中后的回調方法名。它可以為程序提供更好的封裝性,以便更好的進行結構設計。
var router = Router({
'/hello': {
'/usa': 'americas',
'/china': 'asia'
}
}).configure({ resource: container }).init();
var container = {
americas: function() { return true; },
china: function() { return true; }
};