【问题标题】:Cannot read property '@' of null when using $state in onEnter在 onEnter 中使用 $state 时无法读取 null 的属性“@”
【发布时间】:2015-11-15 06:00:54
【问题描述】:

我从 angular-ui-router 收到以下错误:

TypeError: Cannot read property '@' of null
...
TypeError: Cannot read property '@main' of null
...

我已经对可能导致此错误的原因进行了一些研究,并得出的结论是,问题在于当条件为假时我通过 $state.go(state) 进行重定向的事实在另一个状态的 onEnter 期间。

这里有一些关于github上相同问题的讨论:

我尝试了一些建议,但没有奏效。他们似乎没有提供解决方案,只是指出了问题,根据this github讨论应该解决了,但我似乎无法让它工作。

我正在使用 AngularJS v1.2.24 和 ui-router v0.2.11。

使用以下代码(简化):

.state('main', {
    abstract: true,
    url: '/main',
    templateUrl: '/main/_layout.html'
})
.state('main.home', {
    url: '/home',
    templateUrl: '/main/home/home.html',
    controller: 'HomeCtrl',
    onEnter: function ($state)
    {
        if (condition === true){
            $state.go('main.catch')
        }
    }
})
.state('main.catch', {
    url: '/catch',
    templateUrl: '/main/catch/catch.html',
    controller: 'CatchCtrl'
})

有没有办法让它工作?还是我应该考虑采用完全不同的方法来达到相同的结果?

P.S.:一个可能的解决方法是在控制器中执行以下操作,

$scope.$on('$stateChangeSuccess', function(){
    // conditional redirect here
}

但我不想在 HomeCtrl 中这样做。

【问题讨论】:

  • 你是从main.catch重定向到main.catch吗?
  • 哎呀,这是一个错字。它从 main.home 重定向到 main.catch => 更正
  • 如果将条件放入 resolve 而不是 onEnter 会不会有帮助?
  • 看看这个你可以在状态中定义一个函数并且应该能够在那里重定向github.com/angular-ui/ui-router/wiki/URL-Routing
  • @stackg91 哈哈,是的,我做到了。 PS 同时,我能够解决这个问题,并且我自己很快就会回答这个问题。准时 atm 有点低 ;)

标签: angularjs angular-ui-router


【解决方案1】:

我也遇到过类似的情况,是这样解决的:

.state('main.home', {
    url: '/home',
    templateUrl: '/main/home/home.html',
    controller: 'HomeCtrl',
    onEnter: function ($state)
    {
        if (condition === true){
            $timeout(function() {
                $state.go('main.catch')
            )};
        }
    }
})

诀窍是您希望让原始状态更改完成,而不是在状态更改中间尝试重定向。 $timeout 允许完成原始状态更改,然后立即将更改触发到所需状态。

【讨论】:

  • 我建议不要使用 $timeout,而是使用 $state.transition 属性,如果它在那里(否则,不需要 $timeout,它会在不依赖时钟正确的情况下触发.) 例如,试试这个:function afterTransition($state, action) { if ($state.transition) { $state.transition.finally(action); } else { action(); } }
【解决方案2】:

好吧,我知道这有点晚了,但我已经有这个问题很长时间了,我终于通过收听$viewContentLoading事件解决了它:

$rootScope.$on('$viewContentLoading', function(){
    if(!$state.$current.locals)
      $state.$current.locals = {};
});

【讨论】:

    猜你喜欢
    • 2020-08-14
    • 2022-01-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-07-03
    • 1970-01-01
    • 1970-01-01
    • 2020-01-29
    相关资源
    最近更新 更多