Angular - 相同的Url“/”,但根据用户的登录状态使用不同的模板

时间:2022-08-10 12:58:28

I am trying to have two different templates. One that is the landing page for logged out users describing about the business and the other dashboard page for if a user is logged in.

我想要有两个不同的模板。一个是登出用户的登录页面,用于描述用户登录的业务和其他仪表板页面。

I read on this other stack on how to do this with UI-router. I would like to know the best practice to do something similar like this using ngRoute?

我在其他堆栈上阅读了如何使用UI路由器执行此操作。我想知道使用ngRoute做类似这样的事情的最佳做法?

The way it is setup below, is that "/frontdesk" is the dashboard and "/" is the landing page for logged out users. BUT! I want the URL to be the same for whether the user is on the dashboard or is logged out and sent to the landing page! I do not want "/frontdesk", I want "/" for IndexController and FrontdeskController.

下面设置的方式是“/ frontdesk”是仪表板,“/”是已注销用户的登录页面。但!我希望用户是在仪表板上还是注销并发送到登录页面的URL是相同的!我不想要“/ frontdesk”,我希望“/”用于IndexController和FrontdeskController。

Here is my routing JS.

这是我的路由JS。

(function () {
      'use strict';

    angular
      .module('resonanceinn.routes')
      .config(config);

    config.$inject = ['$routeProvider'];

    function config($routeProvider) {
      $routeProvider
        .when('/', { // This is the landing Page
            controller: 'IndexController',
            controllerAs: 'vm',
            templateUrl: '/static/javascripts/layout/index.html'
        })
        .when('/frontdesk', { //This is logged in user that I want to become '/' as well
            controller: 'FrontdeskController',
            controllerAs: 'vm',
            templateUrl: '/static/javascripts/frontdesk/frontdesk.html'
        })
        .when('/register', {
            controller: 'RegisterController', 
            controllerAs: 'vm',
            templateUrl: '/static/javascripts/authentication/register.html'
        })
        .when('/login', {
            controller: 'LoginController',
            controllerAs: 'vm',
            templateUrl: '/static/javascripts/authentication/login.html '
        })
        .when('/:username', {
            controller: 'ProfileController',
            controllerAs: 'vm',
            templateUrl: '/static/javascripts/profiles/profile.html'
        })
        .when('/:username/settings', {
            controller: 'ProfileSettingsController',
            controllerAs: 'vm',
            templateUrl: '/static/javascripts/profiles/settings.html'
     }).otherwise('/');
   }
})();

Solution!

解!

Thank you everyone for your answers.

谢谢大家的答案。

Thanks to @ThibaudL for the better solution.

感谢@ThibaudL提供更好的解决方案。

This is how I ended up doing it:

这就是我最终做到的方式:

In Routes.js

在Routes.js

 .when('/', {
        controller: 'MainController',
        controllerAs: 'vm',
        templateUrl: '/static/javascripts/layout/Main.html'

Main.html

main.html中

<div ng-include="" src="'/static/javascripts/layout/index.html'" ng-if="auth"></div>
<div ng-include="" src="'/static/javascripts/frontdesk/frontdesk.html'" ng-if="!auth"></div>

MainController.js

MainController.js

(function () {
  'use strict';

  angular
    .module('resonanceinn.layout.controllers')
    .controller('StartController', StartController);

  StartController.$inject = ['$scope', '$route', '$routeParams', '$location', 'Authentication'];

  function StartController($scope, $route, $routeParams, $location, Authentication) {

      $scope.auth = Authentication.isAuthenticated();
  }
})();

So now if the user is Authenticated, it just switches the templates to the users dashboard. I added a new div with ng-controller to each template so that each template has their separate controllers.

因此,现在如果用户已通过身份验证,则只需将模板切换到用户仪表板。我为每个模板添加了一个带有ng-controller的新div,以便每个模板都有各自的控制器。

8 个解决方案

#1


3  

What I would do is :

我会做的是:

Main.html

main.html中

<div ng-include="" src="'/static/javascripts/layout/index.html'" ng-if="auth"></div>

MainController.js

MainController.js

(function () {
  'use strict';

  angular
    .module('App.layout.controllers')
    .controller('MainController', MainController);

  MainController.$inject = ['$scope', '$route', '$routeParams', '$location', 'Authentication'];

  function MainController($scope, $route, $routeParams, $location, Authentication) { 

      $scope.auth = Authentication; 
   });
  }
})();

#2


8  

Add another property, like this isGuest: true

添加另一个属性,例如isGuest:true

.when('/', {
        controller: 'IndexController',
        controllerAs: 'vm',
        templateUrl: '/static/javascripts/layout/index.html',
        isGuest: true
})
 .... ...............

and

app.run(function($rootScope, $state, Session) {
 $rootScope.$on("$stateChangeStart", function(event, toState, toParams, fromState, fromParams) {
  if (toState.isGuest == true && Session.isAuthenticated()) {
   // User isn’t authenticated
   // do redirection to guest user
    event.preventDefault();
  }

  if (toState.authentication == true && !Session.isAuthenticated()) {
    // do redirection to loggedin user 
    event.preventDefault();
   }
 });
});

You can write your own service Session,

你可以编写自己的服务会话,

Session.isAuthenticated() // returns true or false,based on whether user is guest or loggedin

Session.isAuthenticated()//根据用户是来宾还是登录返回true或false

#3


4  

You can use resolve property to check if user is logged in.

您可以使用resolve属性检查用户是否已登录。

$routeProvider
    .when('/somepage' ,{
    templateUrl: "templates/template.html",
    resolve:{
        "check":function($location){  
            if('Your Condition'){
                //Do something
            }else{
                $location.path('/');    //redirect user to home.
                alert("You don't have access here");
            }
        }
    }
    })

#4


4  

Inject $locationProvider with your $routeProvider

使用$ routeProvider注入$ locationProvider

config.$inject = ['$locationProvider'];

then

然后

function config($routeProvider, $locationProvider ) {
  $routeProvider
    .when('/', {
        controller: 'IndexController',
        controllerAs: 'vm',
        template: " "
    })

...

...

note its template not templateUrl, also the template is " " note just ""

注意它的模板不是templateUrl,模板也是“”注意只是“”

then in your index controller

然后在你的索引控制器中

.controller('IndexController', function($scope, $route, $routeParams, $location) {
 if ($scope.user.loggedIn) $location.path('/:user'); else $location.path('/:visitor');})

note that same path as '/' but /:user for loggedIn users and /:visitor for anonymous

请注意与'/'相同的路径,但是/:用户对于loggedIn用户和/:访问者为匿名用户

#5


0  

there are a couple of things you can do, the simplest being, checking for a logged in status in the beginning of your FrontdeskController and navigate to the homepage if not logged in.

您可以做一些事情,最简单的方法是,在FrontdeskController的开头检查登录状态,如果没有登录则导航到主页。

you can also add variables on the route and check for them like in the previous answer.

您还可以在路线上添加变量,并像上一个答案中一样检查它们。

there are more extreme cases you can do, which I find to be very bad practice, like writing a double state template page, but again, that's not a good thing to do.

你可以做更多的极端情况,我发现这是非常糟糕的做法,比如写一个双状态模板页面,但同样,这不是一件好事。

I hope this helped

我希望这有帮助

#6


0  

For templateUrl, you can use a function like,

对于templateUrl,您可以使用类似的函数,

templateUrl : function(parameter) {
   if(loggedin) {
       return '/static/javascripts/layout/index.html';
   } else {
       return 'logged out page';
   }
}

You can read $routeProvider,

你可以阅读$ routeProvider,

templateUrl – {string=|function()=} – path or function that returns a path to an html template that should be used by ngView.

templateUrl - {string = | function()=} - 返回应由ngView使用的html模板路径的路径或函数。

If templateUrl is a function, it will be called with the following parameters:

如果templateUrl是一个函数,它将使用以下参数调用:

{Array.< Object >} - route parameters extracted from the current $location.path() by applying the current route

{Array。} - 通过应用当前路由从当前$ location.path()中提取的路由参数

#7


0  

Here's a complete solution:

这是一个完整的解决方案:

var app = angular.module('app', ['ngRoute']);

app.config(function($routeProvider) {
    $routeProvider
        .when('/', {
            controller: 'IndexController',
            controllerAs: 'vm',
            templateUrl: '/static/javascripts/layout/index.html'
        })
        .when('/frontdesk', {
            controller: 'FrontdeskController',
            controllerAs: 'vm',
            templateUrl: '/static/javascripts/frontdesk/frontdesk.html',
            requireLogin: true
        });
});

app.factory('authService', function () {
    var service = {
        isAuthenticated: false,
        loginPageUrl: '/login'
    };

    return service;
});

app.run(function ($rootScope, $location, authService) {
    $rootScope.$on('$routeChangeStart', function (event, next) {
        if (angular.isDefined(next) && next !== null && angular.isDefined(next.requireLogin)) {
            if (next.requireLogin === true && !authService.isAuthenticated) {
                event.preventDefault();
                $location.path(authService.loginPageUrl);
            }
        }
    });
});

#8


0  

First Attempt

第一次尝试

.

In Routes.js

在Routes.js

 .when('/', {
        controller: 'MainController',
        controllerAs: 'vm',
        templateUrl: '/static/javascripts/layout/Main.html'

Main.html

main.html中

<div ng-include="mainTemplate"></div>

MainController.js

MainController.js

(function () {
  'use strict';

  angular
    .module('App.layout.controllers')
    .controller('MainController', MainController);

  MainController.$inject = ['$scope', '$route', '$routeParams', '$location', 'Authentication'];

  function MainController($scope, $route, $routeParams, $location, Authentication) { 

      $scope.$watch(function($scope) {
          return $scope.mainTemplate = Authentication.isAuthenticated() ? '/static/javascripts/layout/index.html' : '/static/javascripts/frontdesk/frontdesk.html';
   });
  }
})();

So now if the user is Authenticated, it just switches the templates to the users dashboard. I added a new div with ng-controller to each template so that each template has their separate controllers.

因此,现在如果用户已通过身份验证,则只需将模板切换到用户仪表板。我为每个模板添加了一个带有ng-controller的新div,以便每个模板都有各自的控制器。

#1


3  

What I would do is :

我会做的是:

Main.html

main.html中

<div ng-include="" src="'/static/javascripts/layout/index.html'" ng-if="auth"></div>

MainController.js

MainController.js

(function () {
  'use strict';

  angular
    .module('App.layout.controllers')
    .controller('MainController', MainController);

  MainController.$inject = ['$scope', '$route', '$routeParams', '$location', 'Authentication'];

  function MainController($scope, $route, $routeParams, $location, Authentication) { 

      $scope.auth = Authentication; 
   });
  }
})();

#2


8  

Add another property, like this isGuest: true

添加另一个属性,例如isGuest:true

.when('/', {
        controller: 'IndexController',
        controllerAs: 'vm',
        templateUrl: '/static/javascripts/layout/index.html',
        isGuest: true
})
 .... ...............

and

app.run(function($rootScope, $state, Session) {
 $rootScope.$on("$stateChangeStart", function(event, toState, toParams, fromState, fromParams) {
  if (toState.isGuest == true && Session.isAuthenticated()) {
   // User isn’t authenticated
   // do redirection to guest user
    event.preventDefault();
  }

  if (toState.authentication == true && !Session.isAuthenticated()) {
    // do redirection to loggedin user 
    event.preventDefault();
   }
 });
});

You can write your own service Session,

你可以编写自己的服务会话,

Session.isAuthenticated() // returns true or false,based on whether user is guest or loggedin

Session.isAuthenticated()//根据用户是来宾还是登录返回true或false

#3


4  

You can use resolve property to check if user is logged in.

您可以使用resolve属性检查用户是否已登录。

$routeProvider
    .when('/somepage' ,{
    templateUrl: "templates/template.html",
    resolve:{
        "check":function($location){  
            if('Your Condition'){
                //Do something
            }else{
                $location.path('/');    //redirect user to home.
                alert("You don't have access here");
            }
        }
    }
    })

#4


4  

Inject $locationProvider with your $routeProvider

使用$ routeProvider注入$ locationProvider

config.$inject = ['$locationProvider'];

then

然后

function config($routeProvider, $locationProvider ) {
  $routeProvider
    .when('/', {
        controller: 'IndexController',
        controllerAs: 'vm',
        template: " "
    })

...

...

note its template not templateUrl, also the template is " " note just ""

注意它的模板不是templateUrl,模板也是“”注意只是“”

then in your index controller

然后在你的索引控制器中

.controller('IndexController', function($scope, $route, $routeParams, $location) {
 if ($scope.user.loggedIn) $location.path('/:user'); else $location.path('/:visitor');})

note that same path as '/' but /:user for loggedIn users and /:visitor for anonymous

请注意与'/'相同的路径,但是/:用户对于loggedIn用户和/:访问者为匿名用户

#5


0  

there are a couple of things you can do, the simplest being, checking for a logged in status in the beginning of your FrontdeskController and navigate to the homepage if not logged in.

您可以做一些事情,最简单的方法是,在FrontdeskController的开头检查登录状态,如果没有登录则导航到主页。

you can also add variables on the route and check for them like in the previous answer.

您还可以在路线上添加变量,并像上一个答案中一样检查它们。

there are more extreme cases you can do, which I find to be very bad practice, like writing a double state template page, but again, that's not a good thing to do.

你可以做更多的极端情况,我发现这是非常糟糕的做法,比如写一个双状态模板页面,但同样,这不是一件好事。

I hope this helped

我希望这有帮助

#6


0  

For templateUrl, you can use a function like,

对于templateUrl,您可以使用类似的函数,

templateUrl : function(parameter) {
   if(loggedin) {
       return '/static/javascripts/layout/index.html';
   } else {
       return 'logged out page';
   }
}

You can read $routeProvider,

你可以阅读$ routeProvider,

templateUrl – {string=|function()=} – path or function that returns a path to an html template that should be used by ngView.

templateUrl - {string = | function()=} - 返回应由ngView使用的html模板路径的路径或函数。

If templateUrl is a function, it will be called with the following parameters:

如果templateUrl是一个函数,它将使用以下参数调用:

{Array.< Object >} - route parameters extracted from the current $location.path() by applying the current route

{Array。} - 通过应用当前路由从当前$ location.path()中提取的路由参数

#7


0  

Here's a complete solution:

这是一个完整的解决方案:

var app = angular.module('app', ['ngRoute']);

app.config(function($routeProvider) {
    $routeProvider
        .when('/', {
            controller: 'IndexController',
            controllerAs: 'vm',
            templateUrl: '/static/javascripts/layout/index.html'
        })
        .when('/frontdesk', {
            controller: 'FrontdeskController',
            controllerAs: 'vm',
            templateUrl: '/static/javascripts/frontdesk/frontdesk.html',
            requireLogin: true
        });
});

app.factory('authService', function () {
    var service = {
        isAuthenticated: false,
        loginPageUrl: '/login'
    };

    return service;
});

app.run(function ($rootScope, $location, authService) {
    $rootScope.$on('$routeChangeStart', function (event, next) {
        if (angular.isDefined(next) && next !== null && angular.isDefined(next.requireLogin)) {
            if (next.requireLogin === true && !authService.isAuthenticated) {
                event.preventDefault();
                $location.path(authService.loginPageUrl);
            }
        }
    });
});

#8


0  

First Attempt

第一次尝试

.

In Routes.js

在Routes.js

 .when('/', {
        controller: 'MainController',
        controllerAs: 'vm',
        templateUrl: '/static/javascripts/layout/Main.html'

Main.html

main.html中

<div ng-include="mainTemplate"></div>

MainController.js

MainController.js

(function () {
  'use strict';

  angular
    .module('App.layout.controllers')
    .controller('MainController', MainController);

  MainController.$inject = ['$scope', '$route', '$routeParams', '$location', 'Authentication'];

  function MainController($scope, $route, $routeParams, $location, Authentication) { 

      $scope.$watch(function($scope) {
          return $scope.mainTemplate = Authentication.isAuthenticated() ? '/static/javascripts/layout/index.html' : '/static/javascripts/frontdesk/frontdesk.html';
   });
  }
})();

So now if the user is Authenticated, it just switches the templates to the users dashboard. I added a new div with ng-controller to each template so that each template has their separate controllers.

因此,现在如果用户已通过身份验证,则只需将模板切换到用户仪表板。我为每个模板添加了一个带有ng-controller的新div,以便每个模板都有各自的控制器。