本文轉自:點擊打開鏈接
今天還是來說一下angular中的路由模塊。我們實際項目中,各個頁面的切換是經常會與Auth相關的。比如我網站的後臺,是需要登錄過的用戶才能進去,那麼我們用angularJS做前端路由的時候應該怎麼完成這個功能呢
------------------------------------------------------------------------
我們還是先設想一個最簡單的場景吧。我們的應用有兩個頁面,登錄頁面後內容頁面,要求是必須要驗證登錄成功後才能進入內容頁面,下面我們一起來實現一下這個例子吧。當然我覺得我的方法可能會比較Low,但是學習階段我們能先把功能做出來比什麼都重要。
首先用bootstrap來寫一個簡單的登錄頁面吧。具體bootstrap代碼我就不說了,我們關注的是angular在這裏面如何用起來
< div class = "col-md-offset-3 col-md-4" > < form class = "form" role = "form" name = "loginForm" ng-submit = "loginCheck()" > < div class = "form-group" > < label class = "control-label" >用戶名</ label > < input type = "text" class = "form-control" required placeholder = "請輸入管理員賬號" ng-model = "admin.username" > </ div > < div class = "form-group" > < label class = "control-label" >密碼</ label > < input type = "password" class = "form-control" ng-model = "admin.pwd" required placeholder = "請輸入密碼" > </ div > < div ng-show = "showError" class = "alert alert-danger alert-dismissible" role = "alert" > < button ng-click = "showError=false" type = "button" class = "close" data-dismiss = "alert" >< span aria-hidden = "true" >×</ span >< span class = "sr-only" >關閉</ span ></ button > 用戶名或密碼錯誤!!你還有一次機會 </ div > < input type = "submit" class = "btn btn-primary btn-lg" value = "登錄" ng-disabled = "loginForm.$invalid" > </ form >
</ div > |
效果如下
id="iframe_0.3253765239649169" src="data:text/html;charset=utf8,%3Cimg%20id=%22img%22%20src=%22http://img.mukewang.com/54788faf000197b405000227.jpg?_=4576483%22%20style=%22border:none;max-width:1571px%22%3E%3Cscript%3Ewindow.onload%20=%20function%20()%20%7Bvar%20img%20=%20document.getElementById('img');%20window.parent.postMessage(%7BiframeId:'iframe_0.3253765239649169',width:img.width,height:img.height%7D,%20'http://www.cnblogs.com');%7D%3C/script%3E" frameborder="0" scrolling="no" style="border-width: initial; border-style: none; width: 500px; height: 227px;">
當然我之前還有一些css的佈局,粘代碼過去可能會出錯哦,至少得在最外層加一個div class="row"
還可以看見,我給登錄按鈕加了個ng-disabled,當表單沒有通過驗證的時候是不能點登錄的。
然後我加了一個提示的tips,用到了ng-show,在controller裏會有一個showError的屬性來控制它的顯示,當驗證賬號密碼錯誤時showError爲true。
當我們驗證出錯的時候
id="iframe_0.5126796091336738" src="data:text/html;charset=utf8,%3Cimg%20id=%22img%22%20src=%22http://img.mukewang.com/547892c90001675104860298.jpg?_=4576483%22%20style=%22border:none;max-width:1571px%22%3E%3Cscript%3Ewindow.onload%20=%20function%20()%20%7Bvar%20img%20=%20document.getElementById('img');%20window.parent.postMessage(%7BiframeId:'iframe_0.5126796091336738',width:img.width,height:img.height%7D,%20'http://www.cnblogs.com');%7D%3C/script%3E" frameborder="0" scrolling="no" style="border-width: initial; border-style: none; width: 486px; height: 298px;">
接着我們來看一下路由
var myApp = angular.module( 'myApp' , [ 'ui.router' , 'myModule' ]); myApp.run( function ($rootScope, $state, $stateParams){ $rootScope.$state = $state; $rootScope.$stateParams = $stateParams; $rootScope.$state.isLogin = false ; }); myApp.config( function ($stateProvider, $urlRouterProvider) { $urlRouterProvider.otherwise( '/login' ); $stateProvider .state( 'login' ,{ url
: '/login' , templateUrl : 'tpls/login.html' , controller : 'LoginController' }) .state( 'index' ,{ url
: '/index' , templateUrl : 'tpls/index.html' , controllerProvider : function ($rootScope){ if ($rootScope.$state.isLogin == false ){ $rootScope.$state.go( 'login' ); } return function (){}; } }); } |
因爲在整個頁面中我們都會用到登錄狀態,所以我把登錄狀態綁定到rootscope中,isLogin剛開始是false表示未登錄。
接着看路由裏面,login這個很簡單,主要看index頁面。
關 鍵的一步就是index的controller,在這裏我選擇用controllerProvider的方式來生成controller,可以看到我們最 後實際上是返回的一個空的function,但是在返回空controller之前(index頁面還沒有解析),我可以做一些事情,那就是驗證權限啦!
如 果$rootScope.$state.isLogin爲false也就是還沒有登錄,那就直接跳轉到登錄頁面。跳轉用到了$state裏面的go方 法,go中的變量就是我們每個頁面的狀態名,也就是state的第一個參數。我是go('login'),它就跳轉到state的第一個參數是login 的那個頁面去了,也就是登錄頁面。換句話說,如果我們登錄提交後驗證沒有成功,當我們在地址欄輸入/index的時候會跳到登錄頁面的哦。
那麼再來看看我們的驗證模塊。
myModule .controller( 'LoginController' , function ($scope,$rootScope,$http){ $scope.showError = false ; $scope.loginCheck = function (){ var username = $scope.admin.username; var pwd = $scope.admin.pwd; var loginSuccess = false ; http.get( '/acm-admin/data/user.json' ) .success( function (response){ for ( var i=0; i<response.length; i++){ if (response[i].username == username && response[i].pwd == pwd){ $rootScope.$state.isLogin = true ; loginSuccess = true ; $rootScope.$state.go( 'index' ); } } if (!loginSuccess){ $scope.showError = true ; } }); } }) |
初 始化我們給showError一個值爲false,不要顯示錯誤提示框。然後來看看驗證登錄的這個方法。首先獲取到用戶輸入的用戶名和密碼,設置登錄成功 的狀態的false。然後通過$http.get,到指定的地方去取一個json文件,很顯然這是個假數據,我們把預設的用戶名和密碼存放到這個json 文件中。取出預設的用戶名和密碼之後就和用戶輸入的來進行對比,相信這都很簡單,大家肯定能看明白。如果用戶名和密碼都對上了,那麼就把登錄狀態設置爲 true,登錄成功也設置爲true。然後用$state的go方法跳轉到Index頁面。
如果登錄信息驗證失敗,那麼就把showError賦爲true,頁面上就會顯示提示信息咯。
----------------------------------------------------------------------------
怎 麼樣,很簡單吧。當然還有其它實現這一功能的方法,而且我上述的方法很可能還有諸多安全隱患,而且模塊的分工也是不明確的,淡然實際部署不推薦這麼寫了。 我們可以優化改進的地方很多,比如驗證的模塊是不是應該獨立出去呢,或者用戶有沒有什麼辦法能輕易繞過這個登錄保護呢?這就留待小夥伴們自己探究了……繼 續學習angular去了,大家晚安!!