angular自帶的angular-router不支持多級路由,第三方的ui-router是基於state的,雖然支持多級路由,但需要寫N多的state,感覺很不爽有沒有?
其實只要我們搞明白下面幾個問題,自己開發一套路由也是很簡單的:
1、當url改變之后,angular如果捕獲到改變事件?
2、如何裝載新的改變事件?
在angular源碼中搜索onUrlChange(~~!竟然真有這個方法):
1 self.onUrlChange = function(callback) { 2 // TODO(vojta): refactor to use node's syntax for events 3 if (!urlChangeInit) { 4 // We listen on both (hashchange/popstate) when available, as some browsers (e.g. Opera) 5 // don't fire popstate when user change the address bar and don't fire hashchange when url 6 // changed by push/replaceState 7 8 // html5 history api - popstate event 9 if ($sniffer.history) jqLite(window).on('popstate', cacheStateAndFireUrlChange); 10 // hashchange event 11 jqLite(window).on('hashchange', cacheStateAndFireUrlChange); 12 13 urlChangeInit = true; 14 } 15 16 urlChangeListeners.push(callback); 17 return callback; 18 };
兩個事件popstate,hashchange 。第一個問題就解決了。
再次搜索onUrlChange:
$browser.onUrlChange(function(newUrl, newState) {//11368行
在這個方法中,我們可以找到兩個通知事件:$locationChangeSuccess,$locationChangeStart,一個是開始改變事件,和改變成功之后的事件,第二個問題也解決。
加上上一篇的動態試圖,再做動態路由就很簡單了。
1 //ui nodule pageview view 2 (function () { 3 var app = angular.module("ui", []); 4 //定義個pageview 用於直接綁定頁面 5 app.directive("pageView", ["$compile", "$location", function ($compile, $location) { 6 return { 7 restrict: "E", 8 link: function (scope, element, attrs) { 9 scope.$on('$locationChangeSuccess', function () { 10 setTimeout(function () { 11 var url = angular.lowercase($location.$$path); 12 var cacheUrl = $(element).data("url"); 13 if (cacheUrl == undefined || url != cacheUrl) { 14 $(element).load(url, function () { 15 if ($(element).contents().length > 0) { 16 angular.compileView($(element).contents()); 17 scope.$broadcast("$locationChangeSuccess"); 18 } 19 }); 20 $(element).data("url", url); 21 } 22 }, 0); 23 }); 24 } 25 }; 26 }]); 27 //定義一個uiview,通過自定義的路由表達式來綁定相應頁面 28 app.directive("uiView", ["$compile", "$location", function ($compile, $location) { 29 return { 30 restrict: "E", 31 scope: { 32 view: "@", 33 exp: "@" 34 }, 35 link: function (scope, element, attrs) { 36 scope.$on('$locationChangeSuccess', function () { 37 setTimeout(function () { 38 var path = $.getUrlParam(scope.view);// getUrlParam(scope.view); 39 var url = scope.exp.replace("{view}", path); 40 var cacheUrl = $(element).data("url"); 41 if (cacheUrl == undefined || url != cacheUrl) { 42 $(element).load(url, function () { 43 if ($(element).contents().length > 0) { 44 angular.compileView($(element).contents()); 45 scope.$broadcast("$locationChangeSuccess"); 46 } 47 }); 48 $(element).data("url", url); 49 } 50 }, 0); 51 }); 52 } 53 }; 54 }]); 55 })();
demo http://files.cnblogs.com/files/jquery-angular/AngularTest.zip