Angular - 相同的 Url "/" 但根据用户的登录状态使用不同的模板
Angular - same Url "/" but with different templates based on user's logged in status
我正在尝试使用两个不同的模板。一个是注销用户的登录页面,用于描述业务,另一个是用户登录时的仪表板页面。
我在 this other stack 上阅读了有关如何使用 UI-router 执行此操作的信息。我想知道使用 ngRoute 做类似这样的事情的最佳实践吗?
下面的设置方式是“/frontdesk”是仪表板,“/”是注销用户的登录页面。 但是!我希望 URL 对于用户是在仪表板上还是已注销并发送到登录页面是相同的!我不想要“/frontdesk”,我想要 IndexController 和 FrontdeskController 的“/”。
这是我的路由 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('/');
}
})();
解决!
谢谢大家的回答。
感谢@ThibaudL 提供更好的解决方案。
这就是我最终的做法:
在 Routes.js
.when('/', {
controller: 'MainController',
controllerAs: 'vm',
templateUrl: '/static/javascripts/layout/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
(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();
}
})();
所以现在如果用户通过身份验证,它只是将模板切换到用户仪表板。
我向每个模板添加了一个带有 ng-controller 的新 div,以便每个模板都有其独立的控制器。
再添加一个属性,像这样isGuest: true
.when('/', {
controller: 'IndexController',
controllerAs: 'vm',
templateUrl: '/static/javascripts/layout/index.html',
isGuest: true
})
.... ...............
和
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();
}
});
});
您可以编写自己的服务Session
、
Session.isAuthenticated()
// returns true
或 false
,取决于用户是访客还是已登录
您可以做几件事,最简单的是在 FrontdeskController 的开头检查登录状态,如果未登录则导航到主页。
您还可以在路线上添加变量并像上一个答案一样检查它们。
你可以做更多的极端情况,我发现这是非常糟糕的做法,比如写一个双状态模板页面,但同样,这不是一件好事。
希望对您有所帮助
您可以使用 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");
}
}
}
})
对于 templateUrl,您可以使用像这样的函数,
templateUrl : function(parameter) {
if(loggedin) {
return '/static/javascripts/layout/index.html';
} else {
return 'logged out page';
}
}
您可以阅读 $routeProvider,
templateUrl – {string=|function()=} – path or function that returns a path to an html template that should be used by ngView.
If templateUrl is a function, it will be called with the following parameters:
{Array.< Object >} - route parameters extracted from the current $location.path() by applying the current route
用你的 $routeProvider 注入 $locationProvider
config.$inject = ['$locationProvider'];
然后
function config($routeProvider, $locationProvider ) {
$routeProvider
.when('/', {
controller: 'IndexController',
controllerAs: 'vm',
template: " "
})
...
注意它的模板不是templateUrl,模板也是“”注意只是“”
然后在你的索引控制器中
.controller('IndexController', function($scope, $route, $routeParams, $location) {
if ($scope.user.loggedIn) $location.path('/:user'); else $location.path('/:visitor');})
请注意与“/”相同的路径,但 /:user 用于登录用户,/:visitor 用于匿名
这是一个完整的解决方案:
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);
}
}
});
});
第一次尝试
.
在 Routes.js
.when('/', {
controller: 'MainController',
controllerAs: 'vm',
templateUrl: '/static/javascripts/layout/Main.html'
Main.html
<div ng-include="mainTemplate"></div>
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';
});
}
})();
所以现在如果用户通过身份验证,它只是将模板切换到用户仪表板。
我为每个模板添加了一个带有 ng-controller 的新 div,以便每个模板都有其独立的控制器。
我会做的是:
Main.html
<div ng-include="" src="'/static/javascripts/layout/index.html'" ng-if="auth"></div>
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;
});
}
})();
我正在尝试使用两个不同的模板。一个是注销用户的登录页面,用于描述业务,另一个是用户登录时的仪表板页面。
我在 this other stack 上阅读了有关如何使用 UI-router 执行此操作的信息。我想知道使用 ngRoute 做类似这样的事情的最佳实践吗?
下面的设置方式是“/frontdesk”是仪表板,“/”是注销用户的登录页面。 但是!我希望 URL 对于用户是在仪表板上还是已注销并发送到登录页面是相同的!我不想要“/frontdesk”,我想要 IndexController 和 FrontdeskController 的“/”。
这是我的路由 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('/');
}
})();
解决!
谢谢大家的回答。
感谢@ThibaudL 提供更好的解决方案。
这就是我最终的做法:
在 Routes.js
.when('/', {
controller: 'MainController',
controllerAs: 'vm',
templateUrl: '/static/javascripts/layout/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
(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();
}
})();
所以现在如果用户通过身份验证,它只是将模板切换到用户仪表板。 我向每个模板添加了一个带有 ng-controller 的新 div,以便每个模板都有其独立的控制器。
再添加一个属性,像这样isGuest: true
.when('/', {
controller: 'IndexController',
controllerAs: 'vm',
templateUrl: '/static/javascripts/layout/index.html',
isGuest: true
})
.... ...............
和
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();
}
});
});
您可以编写自己的服务Session
、
Session.isAuthenticated()
// returns true
或 false
,取决于用户是访客还是已登录
您可以做几件事,最简单的是在 FrontdeskController 的开头检查登录状态,如果未登录则导航到主页。
您还可以在路线上添加变量并像上一个答案一样检查它们。
你可以做更多的极端情况,我发现这是非常糟糕的做法,比如写一个双状态模板页面,但同样,这不是一件好事。
希望对您有所帮助
您可以使用 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");
}
}
}
})
对于 templateUrl,您可以使用像这样的函数,
templateUrl : function(parameter) {
if(loggedin) {
return '/static/javascripts/layout/index.html';
} else {
return 'logged out page';
}
}
您可以阅读 $routeProvider,
templateUrl – {string=|function()=} – path or function that returns a path to an html template that should be used by ngView.
If templateUrl is a function, it will be called with the following parameters:
{Array.< Object >} - route parameters extracted from the current $location.path() by applying the current route
用你的 $routeProvider 注入 $locationProvider
config.$inject = ['$locationProvider'];
然后
function config($routeProvider, $locationProvider ) {
$routeProvider
.when('/', {
controller: 'IndexController',
controllerAs: 'vm',
template: " "
})
...
注意它的模板不是templateUrl,模板也是“”注意只是“”
然后在你的索引控制器中
.controller('IndexController', function($scope, $route, $routeParams, $location) {
if ($scope.user.loggedIn) $location.path('/:user'); else $location.path('/:visitor');})
请注意与“/”相同的路径,但 /:user 用于登录用户,/:visitor 用于匿名
这是一个完整的解决方案:
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);
}
}
});
});
第一次尝试
.
在 Routes.js
.when('/', {
controller: 'MainController',
controllerAs: 'vm',
templateUrl: '/static/javascripts/layout/Main.html'
Main.html
<div ng-include="mainTemplate"></div>
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';
});
}
})();
所以现在如果用户通过身份验证,它只是将模板切换到用户仪表板。 我为每个模板添加了一个带有 ng-controller 的新 div,以便每个模板都有其独立的控制器。
我会做的是:
Main.html
<div ng-include="" src="'/static/javascripts/layout/index.html'" ng-if="auth"></div>
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;
});
}
})();