前言
很久之前便聽說AngularJS,非常酷,最近也比較火,我也在持續關注這個技術,只是沒有認真投入學習。前不久公司找我們部門做一個OA系統(想省下幾萬大洋的費用),第一時間便想到AngularJS,非常適合OA這種單頁應用,再配合Twitter的Bootstrap,能在短時間內做出一套漂亮的系統。當然,很大程度上還是想用實踐來加強自己對新技術的學習,難得公司有這么個好機會!不過,本文的重點不是一步步開發學習,所以此處省去1萬字....
一、問題
AngularJS能如此火有很多原因:雙向綁定、減少DOM操作、AJAX等等。AngularJS的路由機制正是實現頁面無刷新切換的重點,使用hash(#)在頁面內加載模板,而不是跳轉到新的頁面。如果你不是一個強迫證患者,那么一切都無所謂了,但是我終於還是受不了URL中的那個#號,那么問題來了,怎么能去掉它???
二、解決思路
AngularJS團隊不可能考慮不到這個問題,於是有了一個輕輕松松的方法便可以搞定一切,一兩句代碼而已:$locationProvider.html5Mode(true),AngularJS 1.3版本需要在首頁加入<base href="/" />標簽。這樣似乎沒什么問題,URL中的煩人的#號沒了,點擊頁面內鏈接切換也還是AJAX,可是如果你嘗試刷新頁面或者復制URL到瀏覽器中回車的時候,新的問題又來了,報錯!其實不應該驚訝,因為后端用的是ASP.NET MVC,刷新頁面會先匹配ASP.NET MVC的路由機制,如果找不到URL中對應的Controller和Action自然報錯。於是很自然的想到重寫ASP.NET MVC的路由,使它能認識我URL中“不存在”的控制器。
重寫路由要注意幾個問題:
1.幾乎所有路由都需要重定向到/Default/Index,因為這是我的首頁,其余頁面模板都是在這里的ng-view里動態加載的
2.登錄功能的路由不需要重寫,因為這是一個單獨頁面,不會嵌套在/Default/Index中
3.還需要忽略favicon.ico的路由請求,否則網站每次刷新都會有一次多余的請求被定位到/Default/Index中
4.把其它Controller中的Actoin當作數據請求源(請求數據使用web api方式會更好),定義一個新的路由規則,比如:app/{controller}/{action}/{id}
代碼如下:
a).SingleRoute.cs是自定義的路由重定向類,實現所有路由都重寫向到/Default/Index中

public class SingleRoute : RouteBase { public override RouteData GetRouteData(HttpContextBase httpContext) { var data = new RouteData(this, new MvcRouteHandler()); data.Values.Add("controller", "Default"); data.Values.Add("action", "Index"); return data; } public override VirtualPathData GetVirtualPath(RequestContext requestContext, RouteValueDictionary values) { return null; } }
b).RouteConfig.RegisterRoutes代碼修改

public class RouteConfig { public static void RegisterRoutes(RouteCollection routes) { routes.IgnoreRoute("{resource}.axd/{*pathInfo}"); //取消網站圖標的路由請求 routes.IgnoreRoute("favicon.ico"); //AJAX請求數據路由 routes.MapRoute( name: "DefaultApp", url: "app/{controller}/{action}/{id}", defaults: new { controller = "Default", action = "Index", id = UrlParameter.Optional } ); //登錄路由單獨執行 routes.MapRoute( name: "Login", url: "login/{action}/{id}", defaults: new { controller = "Login", action = "Index", id = UrlParameter.Optional } ); //其余所有路由都跳轉到default/index routes.Add(new SingleRoute());//單頁規則 } }
三、總結
問題已解決,記錄並學習