繁体   English   中英

AngularJS UI-Router +需要状态帮助

[英]AngularJS UI-Router + State help needed

我有如下的html代码(代码段1)和JS代码(代码段2)。 在html中,我包括了partials,并构建了一个页面,其中包含一个ui视图,当状态更改时,该视图会动态更改html。 一切正常,该页面包含一个页眉,页脚,左侧菜单以及根据状态动态更改的内容。 现在,我需要为此应用程序添加一个“登录”页面。 但是,我们不需要登录屏幕的header,footer,菜单。 当前,登录屏幕与页眉,页脚和菜单一起显示在定义的单个ui视图中。

我在想是否可以为单独登录定义两个div,如果状态为login则显示该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> code snippet 3:-

 <code> <div ng-show="{$state.is('login')}">Item</div> </code> 

如果我已正确理解它,则要显示登录视图,而没有其他视图(例如页眉,页脚和侧面菜单)。

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

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

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

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

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

请看下面的演示或这个小提琴

注意:演示中的登录名当然是不安全的,仅用于显示视图重定向处理。 在您的应用中,您必须使用$ 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> 

基本上,您可以使用$ state来获取当前状态,例如:

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

$scope.currentState = $state.current;

然后在你的HTML

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

但是嵌套的ui路由器逻辑可能会更有用。

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视图,只是一个命名视图:

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

它只出现在“登录”状态,因为您专门通过它的名称(login-only @ login)来定位它。

您可以在github上的ui-router Wiki帮助页面上的“ 多个命名的视图”中阅读有关它的更多信息。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM