繁体   English   中英

如何在UI-Router中修饰当前状态解析功能?不调用当前函数

[英]How to decorate current state resolve function in UI-Router? Current function isn't invoked

我试图在$stateProvider干,并阻止在每个解析中添加相同的auth函数。 我已经创建了装饰器,在每个状态更改都会将此函数添加到当前状态,但是不调用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-Router内置decorator

decorator(name, func)

允许您扩展(小心)或覆盖(由您自己承担)$ stateProvider内部使用的stateBuilder对象。 这可用于向ui-router添加自定义功能,例如根据州名称推断templateUrl ... 在doc中阅读更多内容

一个工作的plunker

所以,我们可以有这个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;
    }
  }
];

在这里我们只使用装饰器和一些“IF”逻辑

.config(['$stateProvider', 
  function($stateProvider) {

    $stateProvider.decorator('views', function(state, parent) {
      var result = {},
        views = parent(state);

      // some naive example when to not inject resolve
      if (state.name === "home") { 
        return views;
      }
      // child already has that in parent
      if (state.name.indexOf(".") > 0) { 
        return views;
      }

      angular.forEach(views, function(config, name) {

        // here inject the resolve (if not existing)
        config.resolve = config.resolve || {};
        // and extend it with the auth stuff above
        config.resolve.auth = auth;

        result[name] = config;
      });

      return result;
    });

  }
])

后来很少有我们的州,这将由上述东西扩展

$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;
});

更新

我在github上找到了相关的讨论,你可以在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;
        }
      }];
    });
  }
]);

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM