如何在 UI-Router 中装饰当前状态解析功能?当前函数未被调用 [英] How to decorate current state resolve function in UI-Router? Current function isn't invoked

查看:16
本文介绍了如何在 UI-Router 中装饰当前状态解析功能?当前函数未被调用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试在 $stateProvider 中进行 DRY,并防止在每个解析中添加相同的 auth 函数.我创建了装饰器,在每次状态更改时都会将此函数添加到当前状态,但未调用 auth 函数,如何修复它或如何解决讨论的问题?

I'm trying to DRY in $stateProvider and prevent adding the same auth function in each resolve. I've created decorator that in each state change would add this function to current state, but auth function isn't invoked, How to fix it or how to workaround discussed issue?

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:

If I understand your requirement correctly, we can use native UI-Router built-in decorator:

允许您扩展(小心地)或覆盖(自担风险)$stateProvider 内部使用的 stateBuilder 对象.这可用于向 ui-router 添加自定义功能,例如根据状态名称推断 templateUrl... (read 文档中的更多信息)

Allows you to extend (carefully) or override (at your own peril) the stateBuilder object used internally by $stateProvider. This can be used to add custom functionality to ui-router, for example inferring templateUrl based on the state name... (read more in the doc)

一个工作的plunker

所以,我们可以有这个 var auth

So, we can have this 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"逻辑的装饰器

And here we just use decorator with some "IF" logic

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

  }
])

然后是我们的几个状态,它们会被上面的东西扩展

And later few our states, which will be extended by the above stuff

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

在操作中检查它这里

这篇关于如何在 UI-Router 中装饰当前状态解析功能?当前函数未被调用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆