2013-11-28 30 views
6

在定义AngularJS应用程序的路由时,为了指示每个路由应具有的访问级别,为每个路由添加了名为access的新属性。这基于here描述的客户端授权方法。使用异步数据初始化AngularJS配置块

.config块将如下所示:

app.config(['$routeProvider', '$locationProvider', '$httpProvider', 
    function ($routeProvider, $locationProvider, $httpProvider) { 

     var access = routingConfig.accessLevels; //Initialize with asynch data instead 

     $routeProvider. 
     when('/home', { 
      templateUrl: '/Templates/home.html', 
      controller: 'homeController', 
      access: access.user 
     }); 
     $routeProvider. 
     when('/private', { 
      templateUrl: '/Templates/private.html', 
      controller: 'adminController', 
      access: access.admin 
     }); 

     //...more route configurations 

    }]); 

离开了该方法的核心逻辑不谈,我只是想在一般的了解我们如何初始化access变量与一些异步数据,以便它是否可用,同时为每条路线定义access属性?这是必需的,因为只有服务器知道访问级别列表。

虽然有答案Initialize AngularJS service with asynchronous data基础上配置路由使用resolve在服务&露出promise,它不会在我的情况下工作,我需要异步调用定义,因为access路由配置前解决属性取决于异步数据。

我有什么选择? promise/deferred方法仍然可以以某种方式使用吗?

任何建议将不胜感激。

编辑:

来形容access是做了一下,正被称为routingConfig一个单独的模块填充。在approach中,用户可以属于某个被定义为二进制数字的角色。例如public:001,user:010,admin:100(等等)。

任何路由的访问级别将再次是由允许访问它的所有用户角色的OR操作定义的二进制数字。因此对于例如如果user访问级别可以通过用户角色user(010)和admin(100)访问,则其位掩码将为110.稍后要检查路由上的访问权限,我们可以对用户角色和访问权限执行AND操作 - 级别以查看它是否被授权。详情可以在上面的链接中看到。

请注意,服务器端的数据仍然通过更复杂的算法保证安全,因此即使上述逻辑在客户端操作,这样的用户也只能看到任何未经授权页面的标记。

再次回到手中的问题。 access如何在config块中用作属性,并使用来自服务器的异步数据进行初始化。该数据可能看起来像下面这样:

accessLevels : { 
    'public' : '111', 
    'user' : '110', 
    'admin': '100' 
} 
+0

我假设你已经测试服务,以获取'access'但是当你与你的$ routeProvider'使用它的一些原因access'属性的引用将会丢失,并且您以后使用'access'的任何内容都没有更新值?这在我看来很奇怪。 –

+0

你能指定你需要加载'access'(或者广泛描述一些场景)的确切信息吗? (我有几个想法,但它们都不是很优雅) –

+0

这里的问题是,'$ routeProvider'必须在应用程序'runs'注册_before_。我们处理这个问题的方式是定义相同的路由,但在'module.run'函数中设置正确的访问级别,并通过UI无法访问链接。如果用户访问这些链接,他会在应用中看到一个不错的401错误,并且请求使用模式框以更高的权限登录。这是通过'$ http'拦截器处理的。 –

回答

2

所以,如果我理解你正确地应用时应反应迟钝直到access可用。那么,无论如何,异步地抓取access有什么意义呢?

也许这种做法是合适的[肯定在很多类似的情况下,它应该是]:

<script src="angular.js"></script> 
<script> 
angular.module('config').constant(
    <%= // JSON.stringify your config and access %> 
); 
</script> 
<script src="app.js"></script> 

如果你真的要这么做异步然后用XHRHttpRequest或其他方式抢accessbootstrap您的应用程序手动。

0

不知道在此期间是否解决了您的问题,但前段时间我面临同样的问题。我的解决方案是在html标签上使用主控制器以及ng-app。在控制器内部,我使用从服务器收到的访问级别数据,并在$route的帮助下定义了我的路由。因此,在定义路线配置之前,数据是可访问的。您当然也可以在控制器内拨打Auth工厂的承诺then功能,并在那里定义您的路线。

观点:

<html ng-app="app" ng-controller="MainController"> 
... 
</html> 

控制器:

var MainController = ['$scope', '$http', '$route', 'Auth', function ($scope, $http, $route, Auth) { 
    var accessLevels = Auth.accessLevels; 

    $route.routes['/index'] = {templateUrl: "pages/index", controller: IndexController, access: accessLevels.guest}; 
    .... 
    $route.routes['null'] = {redirectTo: '/index', controller: IndexController};