unable to invoke uiCanExit - angular ui router 1.0

2019-06-14 03:16发布

问题:

I have the following routes file in components/app/app-routes.js:

export default
function AppRoutes($stateProvider, $urlRouterProvider, $transitionsProvider) {
  'ngInject';

  // reference: https://ui-router.github.io/guide/ng1/migrate-to-1_0#lazy-resolves
  const defaultResolvePolicy = {
    when: 'EAGER'
  };

  const STATES = [{
    name: 'logout',
    url: '/logout?applicationName&desktopName&sn',
  }, {
    name: 'base',
    url: '',
    abstract: true,
    template: '<ui-view></ui-view>'
  }, {
    name: 'app',
    parent: 'base',
    abstract: true,
    component: 'wireApp',
    data: {
      authRequired: true
    },
    resolvePolicy: defaultResolvePolicy,
    resolve: {
      labels(LabelService) {
        'ngInject';
        return LabelService.fetch();
      },
      settings(SettingsService) {
        'ngInject';
        return SettingsService.fetch();
      },
    }
  }, {
    name: '404',
    url: '/404',
    parent: 'base',
    template: '<w-404></w-404>',
    resolvePolicy: defaultResolvePolicy,
    resolve: {
      module($q, $ocLazyLoad) {
        'ngInject';

        return $q((resolve) => {
          require.ensure([], (require) => {
            let mod = require('pages/404');
            $ocLazyLoad.load({
              name: mod.name
            });
            resolve(mod.name);
          }, '404');
        });
      },
    }
  }, {
    name: 'dashboard',
    parent: 'app',
    url: '/dashboard',
    data: {
      authRequired: true
    },
    views: {
      'content@app': {
        template: '<w-dashboard priority-tasks="$resolve.priorityTasks"></w-dashboard>'
      },
    },
    resolvePolicy: {
      module: defaultResolvePolicy,
      priorityTasks: {
        when: 'LAZY'
      },
    },
    resolve: {
      priorityTasks($http, $q, CacheFactory, CustomerService, RuntimeConfig, PermissionService) {
        'ngInject';

        if (!CacheFactory.get('priorityTasks')) {
          CacheFactory.createCache('priorityTasks', {
            storageMode: 'sessionStorage',
            storagePrefix: 'w'
          });
        }

        const priorityTasksCache = CacheFactory.get('priorityTasks');

        if (PermissionService.check('PRIORITY_TASKS', 'view')) {
          return $http.get(`${RuntimeConfig.DEV_API_URL}/customer/${CustomerService.model.currentCustomer.id}/priority-tasks`, {
            cache: priorityTasksCache
          }).then(({
            data
          }) => data, () => $q.resolve([]));
        }
        return [];
      },
      module($q, $ocLazyLoad) {
        'ngInject';

        return $q((resolve) => {
          require.ensure([], (require) => {
            let mod = require('pages/dashboard');
            $ocLazyLoad.load({
              name: mod.name
            });
            resolve(mod.name);
          }, 'dashboard');
        });
      }
    }
  }, {
    name: 'loans',
    parent: 'app',
    url: '/loans',
    data: {
      authRequired: true
    },
    views: {
      'content@app': {
        template: '<w-loans></w-loans>',
      },
    },
    resolvePolicy: defaultResolvePolicy,
    resolve: {
      security($q, $state) {
        'ngInject';
        //irl get this from a service.
        console.log($transitionsProvider, "TRANSISIONS PROVIDER FROM ROUTE");
        // let permissions = false;
        // if (!permissions) {
        //   return $q.reject("No permissions");
        // }
      },
      module($q, $ocLazyLoad) {
        'ngInject';
        return $q((resolve) => {
          require.ensure([], (require) => {
            let mod = require('pages/loans');
            $ocLazyLoad.load({
              name: mod.name
            });
            resolve(mod.name);
          }, 'loans');
        });
      }
    }
  }];

  $urlRouterProvider
    .when('', '/dashboard')
    .when('/', '/dashboard')
    .when('/login', '/dashboard')
    .otherwise('/404');

  //this will redirect all rejected promises in routes to a 404. 
  $transitionsProvider.onError({
    to: '*',
    from: '*'
  }, (transition) => {
    let $state = transition.router.stateService;
    $state.go('404');
  });

  STATES.forEach((state) => {
    $stateProvider.state(state);
  });


}

in my loans controller (associated state above, 'loans'), however, I am unable to access the new uiCanExit callback.:

   .component('wLoans', {
    template: require('./loans.html'),
    controller: LoansController,
    bindings: {
      settings: '<',
      labels: '<'
    }
  });



 function LoansController($window, $timeout, $http, $compile, $log, $filter, LoansService, ConfigService, ngDialog, SettingsService, CustomerService, ColumnRenderService, $transitions) {
  'ngInject';

  this.uiCanExit = function () {
        console.log("WHY AM I NOT GETTING HERE");
      }
}

nothing appears in the console when I switch between states, and I'm trying to figure out what to do to get the uiCanExit lifecycle hook to be run when I switch in between states (particularly dashboard and loans)

回答1:

I'm not sure about this, but could the problem be caused by not referencing the component directly? Probably this only works when you reference your loans component via the component key instead of placing them in a template which renders the component. I assume that in your case the router tries to find the callback in the (not declared and thus dummy) controller instead of using the component's controller.

Please have a look at the docs: https://ui-router.github.io/docs/latest/interfaces/ng1.ng1controller.html#uicanexit

You can validate this assumption by putting a controller implementation with the uiCanExit() method in your loans state.