使用Angularjs服务的配置在.run()中生成路由

Generate Routes in .run() with config from service Angularjs

本文关键字:路由 run 服务 Angularjs 配置 使用      更新时间:2023-09-26

我正在根据用户有权查看的内容构建路线/状态和菜单。我环顾四周,尝试了一些不同的方法,但我碰壁了。每当调用RoleService.validateRole()时,RoleService工厂中的SessionService对象都是空的。没有添加路线,应用程序实际上已经失效。为什么注入的工厂是空的,而方法是未定义的。

以下是应用程序的简化布局,按依赖关系的顺序启动。

在app.run()中,我将状态添加到应用程序中,而不是在配置中执行。

$stateProviderRef.state(value.stateName, state);

状态来自(工厂)AppConfig.getStates(),它返回一个数组。

var states = AppConfig.getStates();

在getStates()中,我们验证每条路由的角色。

if(RoleService.validateRole(routes[i].role))

RoleService依赖于SessionService,validateRole函数执行此检查:

if(SessionService.currentUser.role === role)

SessionService依赖于AuthenticationService,后者只是一个使用$http(用户对象)返回promise的工厂。SessionService.currentUser是一个函数,.then()是AuthenticationService返回的promise。

 return {
     currentUser: function(){
         AuthenticationService.then(function(result){
             return result;
         });
     }
 };

我不确定有什么更好的方法可以在不包括整个文件的情况下解释代码。

基于plunker(在注释中提到),我将其更新/克隆到另一个正在工作的

I。simple-返回静态数据时(无$http)

因为服务SessoService是这样定义的:

return {
    currentUser: function() {
    ...

我们不能把它称为财产:

...
return {
    validateRoleAdmin: function () {
        if (SessionService.currentUser.role === 'admin') {
        ...
    },
    validateRole: function (role) {
        if(SessionService.currentUser.role === role){
        ...

它是一个必须作为函数currentUser():调用的函数

return {
    validateRoleAdmin: function () {
        if (SessionService.currentUser().role === 'admin') {
        ...
    },
    validateRole: function (role) {
        if(SessionService.currentUser().role === role){
        ...

II。等待异步调用

调整后的示例

接下来,如果我们在示例中创建服务AuthenticationService:的静态结果

angular.module('daedalus').factory('AuthenticationService', 
    function() {
      return {"idsid": "ad_jdschuma","role": "user","id": "33333"}
    }
)

我们不能指望会有这样的方法:

currentUser: function() {
  //AuthenticationService.then(function(result) {
  //  return result;
  //});
  return AuthenticationService;
}

为了使其真正异步,我们可以将其替换为:

angular.module('daedalus').factory('AuthenticationService', 
    ['$timeout', function($timeout) {
    return {
      getData: function() {
        return $timeout(function() {
          return {
            "idsid": "ad_jdschuma",
            "role": "user",
            "id": "33333"
          }
        })
      }
    };     
 }])

然后甚至使用.then()-会话服务:

angular.module('daedalus').factory('SessionService', ['AuthenticationService', 
    function(AuthenticationService) {
        return {
              currentUser: function(){
                    return AuthenticationService
                      .getData()
                        .then(function(result){
                                return result;
                            });
                        }
        };
  }]
)

以及角色服务:

  return {
    ...
    validateRole: function(route) {
      console.log('SessionService currentUser: ' + JSON.stringify(SessionService))
      return SessionService
        .currentUser()
        .then(function(userRole) {
          if (userRole.role === route.role) {
            return route;
          } else {
            return null;
          }
        })
    }

在appConfig 中有了这个

getStates: function(){
    var items = [];
    var deffered = $q.defer();
    var validatedCount = routes.length;
    for(var i=0,len=routes.length; i<len; i++){
      var route = routes[i];
      RoleService
        .validateRole(route) 
        .then(function(route){
            if(route) {
                 items.push(route.stateConfig)
          }
          if(--validatedCount === 0 ){ // all processed
           deffered.resolve(items)
          }
        })
    }
    return deffered.promise;
}

我们可以在运行中做到这一点:

AppConfig
  .getStates()
  .then(function(states) {console.log(states)
    angular.forEach(states, function(value, key) {
      var state = {
        "url": value.url,
        "templateUrl": value.templateUrl,
        "controller": value.controller
      };
      $stateProviderRef.state(value.stateName, state);

    });
    // Configures $urlRouter's listener *after* your custom listener            
    $urlRouter.sync();
  });
$urlRouter.listen();

在这里查看

第二种解决方案(异步)的概念过于.thenified()。我只是想表明一切都在起作用。如何获得安全数据的更好方法在这里完全涵盖:

混淆$locationChangeSuccess和$stateChangeStart