防止触发子状态的UI-Router

6
以下是我在ui-router状态方面的进展:

这是目前为止我使用ui-router状态的情况:

$stateProvider
  .state('tools', {
    url: '/tools/:tool',
    template: '<div ui-view=""></div>',
    abstract: true,
    onEnter: function ($stateParams, $state, TOOL_TYPES) {
      if (TOOL_TYPES.indexOf($stateParams.tool) === -1) {
        $state.go('error');
      }
    }
  })
  .state('tools.list', {
    url: '',
    templateUrl: 'app/tools/tools.tpl.html',
    controller: 'ToolsController'
  })
  .state('tools.view', {
    url: '/:id/view',
    templateUrl: 'app/tools/partials/tool.tpl.html',
    controller: 'ToolController'
  });

从上面的代码可以看出,父状态有一个 tool 参数,该参数只能在 TOOL_TYPES 数组中。因此,在情况下当 tool 不可用时,我想重定向到错误页面。

实际上,一切都按预期进行,但是我收到了两个错误:

TypeError: Cannot read property '@' of null

TypeError: Cannot read property '@tools' of null

因此,我猜测子状态已被“命中”。是否有可能防止这种情况发生?或者也许还有其他方法可以实现我想要的功能?


我认为这可能是ui-router已知的问题。请查看以下链接:https://github.com/angular-ui/ui-router/issues/1434 和 https://github.com/angular-ui/ui-router/issues/1234。 - Aviv Shaked
1个回答

10

Angular ui-router的文档提到,当一个状态变为活动状态时,onEnter回调函数将被调用,因此子状态也会被激活。

要解决这个问题,您需要实现两件事:

  1. 创建一个 resolve ,一旦特定条件不适用于该状态,就返回一个拒绝的承诺。确保传递有关要重定向到的状态的信息。

  2. $rootScope 中创建一个 $stateChangeError 事件处理程序,并使用第六个参数,该参数是您在拒绝的承诺中传递的信息的表示形式。使用这些信息创建您的重定向实现。

演示

Javascript

angular.module('app', ['ui.router'])

  .value('TOOL_TYPES', [
    'tool1', 'tool2', 'tool3'
  ])

  .config(function($stateProvider, $urlRouterProvider) {

    $stateProvider

      .state('error', {
        url: '/error',
        template: 'Error!'
      })

      .state('tools', {
        url: '/tools/:tool',
        abstract: true,
        template: '<ui-view></ui-view>',
        resolve: {
          tool_type: function($state, $q, $stateParams, TOOL_TYPES) {

            var index = TOOL_TYPES.indexOf($stateParams.tool);

            if(index === -1) {
              return $q.reject({
                state: 'error'
              });
            }

            return TOOL_TYPES[index];
          }
        }
      })

      .state('tools.list', {
        url: '',
        template: 'List of Tools',
        controller: 'ToolsController'
      })
      .state('tools.view', {
        url: '/:id/view',
        template: 'Tool View',
        controller: 'ToolController'
      });

  })

  .run(function($rootScope, $state) {
    $rootScope.$on('$stateChangeError', function(
      event, toState, toStateParams, 
      fromState, fromStateParams, error) {

        if(error && error.state) {
          $state.go(error.state, error.params, error.options);
        }

    });
  })

  .controller('ToolsController', function() {})
  .controller('ToolController', function() {});

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接