UI路由器:如何自动从无效状态重定向 [英] UI Router: how to automatically redirect from invalid state

查看:145
本文介绍了UI路由器:如何自动从无效状态重定向的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我建设苏格兰风格的一个多形式.IO 。我用的决心,直到服务模式存在当前步骤的对象限制进入下一步(边点 - 有没有烘干机的方式来做到这一点?)

I'm building a multistep form in the style of scotch.io. I used resolve to restrict access to next steps until the current step's object exists on the service model (side point – is there a DRYer way to do this?).

下面的是我的顶级路线:

Here's are my top-level routes:

angular
  .module('donate')
  .config(routerConfig);

/** @ngInject */
function routerConfig($stateProvider, $urlRouterProvider) {
  $stateProvider
    .state('root', {
      url: '',
      abstract: true,
      views: {
        'donate': {
          controller: 'DonateController as donate',
          templateUrl: 'app/components/donate/donate.html'
        },
        'stories': {
          controller: 'StoriesController as stories',
          templateUrl: 'app/components/stories/views/stories.html'
        }
      }
    });

  $urlRouterProvider.otherwise('/');
}

和这些相关的子路由。

angular
  .module('donate')
  .config(function($stateProvider) {
    $stateProvider
      .state('root.amount', {
        url: '/',
        controller: 'AmountController as amount',
        templateUrl: 'app/components/donate/views/amount.html'
      })
      .state('root.card', {
        url: '/card',
        resolve: {
          amount: function($q,DonateService){
            if(!DonateService.amount){
              var errorObject = {code:'NO_AMOUNT'};
              return $q.reject(errorObject);
            }
          }
        },
        controller: 'CardController as card',
        templateUrl: 'app/components/donate/views/card.html'
        })
      .state('root.billing', {
        url: '/billing-info',
        resolve: {
          card: function($q,DonateService){
            if(!DonateService.card){
              var errorObject = {code:'NO_CARD'};
              return $q.reject(errorObject);
            }
          }
        },
        controller: 'BillingController as billing',
        templateUrl: 'app/components/donate/views/billing.html'
        })
      .state('root.confirm', {
        url:'/confirm',
        resolve: {
          billing: function($q,DonateService){
            if(!DonateService.email){
              var errorObject = {code:'NO_BILLING_INFO'};
              return $q.reject(errorObject);
            }
          }
        },
        controller: 'ConfirmController as confirm',
        templateUrl: 'app/components/donate/views/confirm.html'
      })
      .state('root.success', {
        url:'/success',
        controller: 'SuccessController as success',
        templateUrl: 'app/components/donate/views/success.html'
      })
      .state('root.error', {
        url:'/error',
        controller: 'ErrorController as error',
        templateUrl: 'app/components/donate/views/error.html'
      });
  });

错误报告一点点

在父控制器prevents用户此开关可通过点击导航步时,孩子们的拒绝承诺设立上面跳跃到下一个步骤。

A little bit of error reporting

This switch on the parent controller prevents users from jumping to the next step by clicking on the step nav when the the children's reject the promise set up above.

angular
  .module('donate')
  .controller('DonateController', DonateController);

DonateController.$inject = ['DonateService', '$rootScope', '$state', '$log'];

/* @ngInject */
function DonateController(DonateService, $rootScope, $state, $log) {
  var vm = this;
  vm.DonateService = DonateService;

  $rootScope.$on('$stateChangeError', stateError);

  function stateError (e, toState, toParams, fromState, fromParams, error) {
    switch (error.code) {
      case 'NO_AMOUNT':
        $log.debug('State Error:', error.code);
        $state.go('root.amount');
        break;
      case 'NO_CARD':
        $log.debug('State Error:', error.code);
        $state.go('root.card');
        break;
      case 'NO_BILLING_INFO':
        $log.debug('State Error:', error.code);
        $state.go('root.billing');
        break;
      default:
        $log.debug('State Error:', error.code);
        $state.get('error').error = error;
        $state.go('root.amount');
    }
  }
}

问题

这工作顺顺当当。当用户试图点击一个人迹罕至一步的导航丸,控制台尽职尽责嗝出来的错误信息或三个。但有一个问题仍然是:用户可以浏览(通过地址栏),以/卡/计费信息和/确认,他们会用一个空白视图映入眼帘,没有控制台输出可言

The Question

This works swimmingly. When a user tries to click on an inaccessible step's nav pill, the console dutifully belches out an error message or three. But one problem remains: Users can browse (via the URL bar) to /card, /billing-info and /confirm and they'll be greeted with a blank view, with no console output to speak of.

我如何把它挂,这样谁浏览任何将用户路由他们不应该在被退回到开始(或者甚至更好,最后完成的状态)?

How do I hook it so that users who browse to any route they aren't supposed to be on are bounced back to the beginning (or, even better, the last completed state)?

推荐答案

移动 $ rootScope。$的() runBlock 解决了这个问题。

Moving $rootScope.$on() to the runBlock solved the problem.

这篇关于UI路由器:如何自动从无效状态重定向的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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