angular-ui-router:解析根状态

9 angularjs angular-ui-router

据我了解ui.router

你有$ stateProvider

在其中你可以写$ stateProvider.state()

你可以写

    .state('account', {
        url: '/account',
        template: '<ui-view/>'
    })
    .state('account.register', {
        url: '/register',
        templateUrl: '/account/views/register.html',
        data: { title: 'Create Account' },
        controller: 'AccountRegister'
    })
Run Code Online (Sandbox Code Playgroud)

但'帐户'是某种根状态的孩子.

所以我的想法是,ui.router的根状态有一个<ui-view/>,就像'account'模板一样'<ui-view/>',所以index.html就是根状态.甚至'home'url: '/'将或者更确切地说,是这根状态的孩子.

如果我能够访问根状态并说它应该解析用户服务,那么这个已解决的值应该在所有状态上可用(或者更好地在每个状态是根状态的子状态,也就是所有状态).用户服务承诺生成a $http.get('/api/user/status')并返回.{"user":{id: "userid", role: "role"}} or {"user":null} 这将保证始终填充用户服务返回的值.

如何访问根状态并说它应该解决,例如User.get()

或者让我重新说一下.

所有控制器都应该可以使用用户对象.有关当前登录用户的信息由$ http.get('/ api/user/status')提供.这就是问题,我正在寻找一个DRY解决方案,假设api正在服务,它是100%安全的假设设置了一个用户对象,即承诺总是被履行,也就是"在继续之前等待承诺解决".

sti*_*tes 5

免责声明 - 搞乱你的根范围并不是一个好主意.如果你正在阅读这篇文章,请注意OP,@ dalu已经完成了这条路线,并用http拦截器解决了他的问题.仍然 - 回答这个问题非常有趣,所以你可能喜欢自己尝试一下:


这可能有点晚了,但这里有

正如评论中提到的,根据我迄今为止的经验,这与ui-router的api(v0.2.13)无法实现,因为它们已经声明了真正的根状态,名为"".看起来在过去的几年中有关于你正在寻找什么的拉动请求,但它看起来不像是在任何地方.

根状态的属性如下:

{
    abstract: true,
    name: "",
    url: "^",
    views: null
}
Run Code Online (Sandbox Code Playgroud)

也就是说,如果你想扩展路由器来添加这个功能,你可以通过装饰$stateProvider:

$provide.decorator('$state', function($delegate) {
  $delegate.current.resolve = {
    user: ['User', '$stateParams', httpRequest]
  };
  return $delegate
});
Run Code Online (Sandbox Code Playgroud)

请注意,有两个currents:$delegate.current- 原始""状态 - 和$delegate.$current- 它的包装器.

不过,在找到你想要的解决方案之前,我发现了一些障碍.每次导航到新状态时,您都会发出另一个必须在前进之前解决的请求.这意味着这个解决方案并不比事件处理$stateChangeStart或某些"top"状态好得多.我可以想到三个最糟糕的解决方案:

  • 首先,缓存您的http呼叫.除了我可以看到这几乎是如何使某些用例无效,也许你正在做一些会话.
  • 接下来,使用您的一个单独选项(控制器/服务)有条件地进行调用(可能只是为第一次加载设置一个标志).由于国家被拆除,它的控制器可能也是如此 - 服务可能是你唯一的选择.
  • 最后,研究一些其他的路由方式 - 我没有过多使用ui.router-extras,但粘性状态深度状态重定向可能会成功.

我想,最后,我有义务提醒你要注意你在根级工作的事实.所以,我的意思是,在根级别做任何事情的时候要小心.

我希望这回答了你的问题!

  • +1我会在顶部添加一个免责声明 - 我在底部提到你不应该在根范围内进行评论......但我不想太过刻意,因为那似乎正是什么问题是要求. (3认同)

mra*_*hal 5

从ui-router开始,1.0.0-beta.3您现在可以使用转换钩子轻松完成此操作:

angular
  .module('app')
  .run(run);

function run($transitions, userService) {

  // Load user info on first load of the page before showing content.
  $transitions.onStart({}, trans => {

    // userService.load() returns a promise that does the job of getting
    // user info and populating a field with it (you can do whatever you like of course).
    // Just remember to finally return `true`.
    return userService
      .load()
      .then(() => true);
  });
}
Run Code Online (Sandbox Code Playgroud)

在继续加载州之前,州经理将等待承诺解决.

重要提示:确保userService仅加载其数据一次,并且当它已经加载时,它应该只返回已经解决的承诺.因为上面的回调将在每个状态转换时调用.例如,要处理登录/注销,您可以userService.invalidate()在执行登录/注销之后但在执行之前创建并调用它$state.reload().

  • 考虑到诸如/sf/answers/1577833771/等流行解决方案的繁琐程度,这非常好 (2认同)