需要AngularJS UI-Router + State帮助

时间:2016-05-03 18:12:23

标签: javascript html angularjs angular-ui-router

我有html代码(代码段1)& JS代码(代码片段2)如下。 在HTML中我包括部分 并构建一个包含动态更改html的ui视图的页面 当国家改变。这工作正常。页面包含 标题,页脚,左侧菜单以及基于状态的动态变化内容。 现在我需要为此应用程序包含一个Login页面。但是我们并不需要 页眉,页脚,登录屏幕的菜单。 目前,登录屏幕显示在与页眉,页脚和菜单一起定义的单个ui视图中。

我在想是否可以为登录单独定义两个div,如果状态是登录则显示div。如果状态未登录,则显示下面的html代码中显示的div(代码段1)。请告知这是否可行。如果是这样,请告知如何访问html中的状态。我尝试使用下面的代码(代码段3)访问该状态,但无法提供建议。

html(代码段1):

<code>
    <div class="grandContainer">    
    <div ng-include="'${header}'"></div>
    <div class="abc">
            <div ng-include="'${status}'"></div>
            <div ng-include="'${menu}'"></div>
    </div>      
    <div class="mainContainer">
    <div ui-view></div>
    </div>

    <p ng-include="'${footer}'"></p> 
</div>
</code>  

JS(代码段2):

app.config(['$stateProvider','$urlRouterProvider',function($stateProvider,   $urlRouterProvider) {  
    $urlRouterProvider.otherwise('/login');
    $stateProvider.state('grid', {
    url: '/grid',
    templateUrl: 'resources/html/grid.html',
    controller: 'gridCtrl'
    }).state('chDetail', {
     url: "/chDetail/:chId",
     templateUrl: "resources/html/chDetail.html",
     controller: 'chDetailCtrl'
     }).state('login', { 
     url: "/login",
     templateUrl: "resources/html/login.html",
     controller: 'loginCtrl'
     });
     }]).controller('gridCtrl', ['$scope', function($scope){
     $scope.grid =[];
     }]);

</code>

code snippet 3:-

app.config(['$stateProvider','$urlRouterProvider',function($stateProvider,   $urlRouterProvider) {  
    $urlRouterProvider.otherwise('/login');
    $stateProvider.state('grid', {
    url: '/grid',
    templateUrl: 'resources/html/grid.html',
    controller: 'gridCtrl'
    }).state('chDetail', {
     url: "/chDetail/:chId",
     templateUrl: "resources/html/chDetail.html",
     controller: 'chDetailCtrl'
     }).state('login', { 
     url: "/login",
     templateUrl: "resources/html/login.html",
     controller: 'loginCtrl'
     });
     }]).controller('gridCtrl', ['$scope', function($scope){
     $scope.grid =[];
     }]);

</code>

3 个答案:

答案 0 :(得分:1)

如果我已正确理解你想要显示登录视图而不显示其他视图,如页眉,页脚和&amp;侧面菜单。

然后,您可以使用您的观看次数headerfooterside-menu等为布局创建抽象状态,并为您的登录视图添加单独的状态。

演示的棘手部分是抽象状态下的视图定义:

abstract: true,
views: {
    '': {
        templateUrl: 'layout.html',
    },
    'header@root': {
        template: 'content for header'
    },
    'footer@root': {...}
}

抽象状态在做什么?抽象状态将在主模板的未命名视图中加载布局模板,并加载您要与子状态共享的其他视图。

然后,每个子状态都可以根据需要定义内容视图并重新使用其他视图。

请查看下面的演示或此fiddle

注意:的 演示中的登录当然不安全,只在那里显示视图重定向处理。在你的应用程序中,你必须使用$ http和sessionStorage和令牌。

angular.module('demoApp', ['ui.router'])
	.run(function($rootScope, $state) {
            $rootScope.$on('$stateChangeError', function(evt, to, toParams, from, fromParams, error) {
          if (error.redirectTo) {
            $state.go(error.redirectTo);
          } else {
            $state.go('error', {status: error.status})
          }
        })
    })
	.factory('userService', userService)
	.config(routes);

function userService() {
	var usersMock = {
    	'testUser': {
        	username: 'testUser',
            password: '1234'
        },
        'testUser2': {
        	username: 'testUser2',
            password: '1234'
        }
    };
	var userService = {
    	user: undefined,
    	login: function(userCredentials) {
        	// later --> $http.post('auth', userCredentials).then(...)
            // for demo use local data
            var user = usersMock[userCredentials.username]
            userService.user = ( user && ( user.password == userCredentials.password ) ) ? 
            	user : undefined;
            return user;
        },
        logout: function() {
        	userService.user = undefined;
        }
    }
    
    return userService;
}
function routes($urlRouterProvider, $stateProvider) {

	$urlRouterProvider.otherwise('/');
    
    $stateProvider
    	.state('root', {
        	url: '',
        	abstract:true,
            resolve: {
            	'user': function(userService) {
                	return userService.user; // would be async in a real app
                }
            },
            views: {
            	'': {
                	templateUrl: 'layout.html',
                },
            	'header@root': {
                	template: '<h1>header View<span ng-if="user"><button ng-click="logout()">logout</button></span><span ng-if="!user"><button ng-click="login()">login</button></span></h1>',
                    controller: function($scope, $state, user, userService) {
                    	$scope.user = user;
                        $scope.login = function() {
                        	$state.go('login');
                        };
                        $scope.logout = function() {
                        	userService.logout();
                            $state.go('root.home', {}, {reload: true});
                        };
                    }
            	},
                'footer@root': {
                    template: '<p>footer view</p>'
                }
            }
        })
    	.state('root.home', {
            url: '/',
            views: {
                'content': {
                    template: 'Hello at home'
                }
            }
        })
        .state('root.about', {
            url: '/about',
            views: {
                'content': {
                    template: 'about view'
                }
            }
    	})
        .state('root.restricted', {
            url: '/restricted',
            resolve: {
            	auth: function(userService, $q, $timeout) {
                
                	var deferred = $q.defer();
                	/* //with an async
                    return UserService.load().then(function(user){
                      if (permissionService.can(user, {goTo: state})) {
                        return deferred.resolve({});
                      } else {
                        return deferred.reject({redirectTo: 'some_other_state'});
                      }
                    }*/
                    
                   $timeout(function() {
                        if ( angular.isUndefined(userService.user) ) {
                            return deferred.reject({redirectTo: 'login'});
                        }
                        else {
                            return deferred.resolve(userService.user);
                        }
                    });
                    
                    return deferred.promise;
                }
            },
            views: {
                'content': {
                    template: 'this is only visible after login. Hello {{user}}!',
                    controller: function($scope, auth) {
                    	$scope.user = auth.username;
                    }
                }
            }
    	})
        .state('login', {
            url: '/login',
            templateUrl: 'views/login.html',
            controller: function($scope, $state, userService) {
            	$scope.login = function(cred) {
                	var user = userService.login(cred);
                    
                    if (angular.isUndefined(user)) {
                    	alert('username or password incorrect.')
                    }
                    else {
                    	$state.go('root.restricted');
                    }
                };
            }
        });
}
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular-ui-router/0.2.18/angular-ui-router.js"></script>

<div ng-app="demoApp">
    <a ui-sref="root.home" href="#">home</a>
    <a ui-sref="root.about" href="#">about</a>
    <a ui-sref="root.restricted" href="#">restricted page</a>
    
    <div ui-view>
    </div>
    
    <script type="text/ng-template" id="views/login.html">
    	<h1>Login</h1>
        <p>Try testUser and 1234 as credentials</p>
        <label>Username</label><input ng-model="userCred.username"/>
        <label>Password</label><input type="password" ng-model="userCred.password"/>
        <button ng-click="login(userCred)">login</button>
    </script>
    
    <script type="text/ng-template" id="layout.html">
    	<div>
            <div ui-view="header"></div>
            <div ui-view="content"></div>
            <div ui-view="footer"></div>
    	</div>
    </script>
</div>

答案 1 :(得分:0)

非常基本上你可以使用$ state来获取当前状态,如:

module.exports = function Controller($state, $scope)

$scope.currentState = $state.current;

然后在你的HTML中

<p ng-if="currentState !='login'" ng-include="'${footer}'"></p>

但是嵌套的ui-router逻辑可能更有用。

答案 2 :(得分:0)

app.config(['$stateProvider','$urlRouterProvider',
  function($stateProvider,   $urlRouterProvider) {  
    $urlRouterProvider.otherwise('/login');
    $stateProvider.state('grid', {
      url: '/grid',
      templateUrl: 'resources/html/grid.html',
      controller: 'gridCtrl'
    })
    .state('chDetail', {
      url: "/chDetail/:chId",
      templateUrl: "resources/html/chDetail.html",
      controller: 'chDetailCtrl'
    })
    .state('login', { 
      url: "/login",
      controller: 'loginCtrl',
      views: {
        '': {
          templateUrl: 'resources/html/login.html'
        },
        'login-only@login': {
          templateUrl: 'resources/html/other-html.html'
        }
      }
    });
  }
])
.controller('gridCtrl', ['$scope', function($scope){
  $scope.grid =[];
}]);

我稍微改了一下。要获得所需内容,请使用视图。

然后你的额外代码就是另一个ui-view,只是一个命名的代码:

<div ui-view="login-only"></div>

它只会出现在'登录'状态,因为您通过它的名称(仅登录@登录)专门定位它。

您可以在github的ui-router wiki帮助页面的Multiple Named Views上阅读更多相关信息。