Javascript 如何布置UI路由器中的当前状态解析功能?当前函数为';t调用

Javascript 如何布置UI路由器中的当前状态解析功能?当前函数为';t调用,javascript,angularjs,angular-ui-router,angular-decorator,Javascript,Angularjs,Angular Ui Router,Angular Decorator,我正在尝试在$stateProvider中干燥,并防止在每个解析中添加相同的auth函数。我已经创建了decorator,在每次状态更改时都会将此函数添加到当前状态,但不会调用auth函数,如何修复它或如何解决讨论的问题 app.config(function ($stateProvider, $urlRouterProvider, $provide) { $provide.decorator('$state', function($delegate, $rootScope) { $

我正在尝试在
$stateProvider
中干燥,并防止在每个解析中添加相同的
auth
函数。我已经创建了decorator,在每次状态更改时都会将此函数添加到当前状态,但不会调用
auth
函数,如何修复它或如何解决讨论的问题

app.config(function ($stateProvider, $urlRouterProvider, $provide) {
  $provide.decorator('$state', function($delegate, $rootScope) {
    $rootScope.$on('$stateChangeStart', function(event, state, params) {
      if ($delegate.current === "login" || $delegate.current === "register") {
        return;
      }
      console.log("decorator", $delegate);
      $delegate.current.resolve = {
        auth: ['AuthService', '$stateParams', function(AuthService, $stateParams) {
          //how to invoke this function?
          if (AuthService.isAuthenticated()) {
            return AuthService.me(); //promise
          } else {
            return false;
          }
        }]
      };
    });
    return $delegate;
  });
国家定义:

  $stateProvider.state('root', {
    abstract: true,
    url: '/',
    views: {
      "": {
        controller: 'RootCtrl',
        templateUrl: 'views/root.html'
      },
      "header@root": {
        templateUrl: 'views/header.html'
      }
    }
  })
  .state('root.home', {
    url: urlPrefix,
    views: {
      "content@artworks": {
        templateUrl: 'views/home.html',
        //resolve: {
        //  auth: ['AuthService', '$stateParams', function(AuthService, $stateParams) {
        //  }]
        //}
      }
    }
  })
  ...

如果我正确理解您的要求,我们可以使用本机
UI路由器
内置
装饰器

允许您(小心地)扩展或覆盖$stateProvider内部使用的stateBuilder对象(自行承担风险)。这可用于向ui路由器添加自定义功能,例如根据状态名称推断templateUrl。。。(读)

因此,我们可以使用这个
var auth

var auth = ['AuthService', '$stateParams',
  function(AuthService, $stateParams) {
    //how to invoke this function on needed states?
    if (AuthService.isAuthenticated()) {
      return AuthService.me();
    } else {
      return false;
    }
  }
];
在这里,我们只是使用带有一些“如果”逻辑的decorator

然后我们几个州,这些州会被上面的东西扩展

$stateProvider
    .state('home', {
      url: "/home",
      templateUrl: 'tpl.html',
    })
    .state('parent', {
      url: "/parent",
      templateUrl: 'tpl.html',
      controller: 'SharedCtrl',
    })
    .state('parent.child', {
      url: "/child",
      templateUrl: 'tpl.html',
      controller: 'SharedCtrl',
    });

在操作中检查它

我意识到,
$delegate.current
对象只包含原始stateProvider配置数据。要包装解析函数,我会在每次状态更改时将函数添加到
$delegate.$current

$provide.decorator('$state', function($delegate, $rootScope) {
  $rootScope.$on('$stateChangeStart', function(event, state, params) {
    if ($delegate.current === "err404" || $delegate.current === "login" || $delegate.current === "register") {
      return;
    }
    console.log("decorator", $delegate);
    $delegate.$current.resolve["auth"] = ['AuthService', '$stateParams', function(AuthService, $stateParams) {
      if (AuthService.isAuthenticated()) {
        console.log('AuthService.me()');
        return AuthService.me();
      } else {
        return false;
      }
    }]
  });
  return $delegate;
});
更新

我在上找到了相关讨论,您可以在
toState
param中添加通用解析函数:

app.run(['$rootScope', '$state',
  function($rootScope, $state) {

    $rootScope.$on('$stateChangeStart', function(event, toState) {

      if (toState.name === "login" || toState.name === "register") {
        return;
      }

      toState["resolve"]["auth"] = ['AuthService', '$stateParams', function(AuthService, $stateParams) {
        if (AuthService.isAuthenticated()) {
          return AuthService.me();
        } else {
          return false;
        }
      }];
    });
  }
]);

我的经验是,如果您在调整提供程序之前配置状态,则此操作不起作用。在我的设置中,我在应用程序依赖的子模块中定义状态,因此在主应用程序配置能够调整状态构建过程之前对其进行配置。但这可以通过将statebuilder配置移动到所需的第一个子模块中来解决,这样它将在加载其他子模块之前应用。希望能帮助经历过类似行为的人。@AirBorne04-好的一点,我认为从示例中可以清楚地看出。。。但是,如果您设置了多个模块,每个模块都声明自己的配置,那么thanksAlso似乎不起作用-
app.run(['$rootScope', '$state',
  function($rootScope, $state) {

    $rootScope.$on('$stateChangeStart', function(event, toState) {

      if (toState.name === "login" || toState.name === "register") {
        return;
      }

      toState["resolve"]["auth"] = ['AuthService', '$stateParams', function(AuthService, $stateParams) {
        if (AuthService.isAuthenticated()) {
          return AuthService.me();
        } else {
          return false;
        }
      }];
    });
  }
]);