尝试避免使用 $rootScope 时路由更改事件
Route change events while trying to avoid using $rootScope
根据 Angular team (and severals blogs) 的建议,我尽量避免在我的应用程序中使用 $rootScope
。
$rootScope
exists, but it can be used for evil
"Of course, global state sucks and you should use $rootScope
sparingly,
like you would (hopefully) use with global variables in any language.
In particular, don't use it for code, only data. If you're tempted to
put a function on $rootScope
, it's almost always better to put it in a
service that can be injected where it's needed, and more easily
tested." - from Angular FAQ
但在我的一个应用程序中,我多次使用 $routeChangeStart
等事件 广播事件 使用 $rootScope
:
/* Force redirection to home page when a connected user calls login page */
$rootScope.$on("$routeChangeStart", function(event, next, current) {
if(next.$$route.originalPath == '/login' && Session.isUserConnected()) {
$location.path("/home");
}
}
在这些情况下,我找不到避免 $rootScope
的方法。
- 有没有更优雅的方法来实现这种技巧?
- 我的应用使用它是不是设计错误?
- 我必须在绝对必要时放弃使用它吗?
如果您希望我提供更多代码示例,请告诉我。
如果你不想在这种情况下使用 $rootScope
你可以使用强大的 resolve
.
因为我看到您正在使用 ngRoute
模块,所以我创建了 ngRoute
的 Plunker 和代码 resolve.I 如果您需要,可以为 ui-router
创建一个还有。
使用 Resolve 使代码执行得更快,因为它不会经过 DigestCycle
您可以通过注入会话从 Session.isUserConnected()
中获取用户标志。
然后您可以使用该变量来重定向路由。
// Code goes here
angular.module('Test', ['ngRoute'])
.config(function($routeProvider) {
var user = true;
//var user = Session.isUserConnected(); You can use your logic here
$routeProvider
.when("/login", {
template: "Login View",
resolve: {
data: function($q, $timeout,$location) {
var deferred = $q.defer();
$timeout(function() {
if (user) {
$location.path("/home");
deferred.reject();
} else {
deferred.resolve();
}
});
return deferred.promise;
}
}
})
.when("/home", {
template: "Home View. It is redirected from Login by checking the user condition. Without using the rootscope",
})
.otherwise({redirectTo:'/login'});
})
<!DOCTYPE html>
<html ng-app="Test">
<head>
<link rel="stylesheet" href="style.css" />
</head>
<body>
<div ng-view></div>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.15/angular.js"></script>
<script src="http://angular-ui.github.io/ui-router/release/angular-ui-router.js"></script>
<script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.5.0/angular-route.js"></script>
</body>
</html>
这里是主要部分:
data: function($q, $timeout, $location) {
var deferred = $q.defer();
$timeout(function() {
if (user) {
$location.path("/home");
deferred.reject();
} else {
deferred.resolve();
}
});
return deferred.promise;
}
你看错了。
首先,这个事件是由 Angular 团队添加的 - 你认为他们建议不要使用它吗?:D 那篇文章是关于你不应该把所有东西都放在 $rootScope 中,这似乎是一个简单的方法初学者。
实际上,使用 $rootScope
- 对于全球事件绝对没问题 -- 这就是此服务的实际目的。
根据 Angular team (and severals blogs) 的建议,我尽量避免在我的应用程序中使用 $rootScope
。
$rootScope
exists, but it can be used for evil"Of course, global state sucks and you should use
$rootScope
sparingly, like you would (hopefully) use with global variables in any language. In particular, don't use it for code, only data. If you're tempted to put a function on$rootScope
, it's almost always better to put it in a service that can be injected where it's needed, and more easily tested." - from Angular FAQ
但在我的一个应用程序中,我多次使用 $routeChangeStart
等事件 广播事件 使用 $rootScope
:
/* Force redirection to home page when a connected user calls login page */
$rootScope.$on("$routeChangeStart", function(event, next, current) {
if(next.$$route.originalPath == '/login' && Session.isUserConnected()) {
$location.path("/home");
}
}
在这些情况下,我找不到避免 $rootScope
的方法。
- 有没有更优雅的方法来实现这种技巧?
- 我的应用使用它是不是设计错误?
- 我必须在绝对必要时放弃使用它吗?
如果您希望我提供更多代码示例,请告诉我。
如果你不想在这种情况下使用 $rootScope
你可以使用强大的 resolve
.
因为我看到您正在使用 ngRoute
模块,所以我创建了 ngRoute
的 Plunker 和代码 resolve.I 如果您需要,可以为 ui-router
创建一个还有。
使用 Resolve 使代码执行得更快,因为它不会经过 DigestCycle
您可以通过注入会话从 Session.isUserConnected()
中获取用户标志。
然后您可以使用该变量来重定向路由。
// Code goes here
angular.module('Test', ['ngRoute'])
.config(function($routeProvider) {
var user = true;
//var user = Session.isUserConnected(); You can use your logic here
$routeProvider
.when("/login", {
template: "Login View",
resolve: {
data: function($q, $timeout,$location) {
var deferred = $q.defer();
$timeout(function() {
if (user) {
$location.path("/home");
deferred.reject();
} else {
deferred.resolve();
}
});
return deferred.promise;
}
}
})
.when("/home", {
template: "Home View. It is redirected from Login by checking the user condition. Without using the rootscope",
})
.otherwise({redirectTo:'/login'});
})
<!DOCTYPE html>
<html ng-app="Test">
<head>
<link rel="stylesheet" href="style.css" />
</head>
<body>
<div ng-view></div>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.15/angular.js"></script>
<script src="http://angular-ui.github.io/ui-router/release/angular-ui-router.js"></script>
<script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.5.0/angular-route.js"></script>
</body>
</html>
这里是主要部分:
data: function($q, $timeout, $location) {
var deferred = $q.defer();
$timeout(function() {
if (user) {
$location.path("/home");
deferred.reject();
} else {
deferred.resolve();
}
});
return deferred.promise;
}
你看错了。 首先,这个事件是由 Angular 团队添加的 - 你认为他们建议不要使用它吗?:D 那篇文章是关于你不应该把所有东西都放在 $rootScope 中,这似乎是一个简单的方法初学者。
实际上,使用 $rootScope
- 对于全球事件绝对没问题 -- 这就是此服务的实际目的。