angular学习笔记之动态路由

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    https://files.cnblogs.com/files/jquery-angular/AngularTest.zip

posted @ 2015-07-21 12:06  *小眼睛*  阅读(2835)  评论(0编辑  收藏  举报