Angular 1.5 компонентный маршрутизатор $canActivate: доступ к следующему маршруту и ​​изменение маршрута в случае отсутствия данных

У меня на самом деле есть три проблемы с $canActivate (также посмотрите код ниже, чтобы лучше понять проблемы):

  1. При нажатии на <a ng-link="['MachineDetails', { id: 'c6bd76947fc0' }]</a> Я не могу получить доступ к идентификатору из $canActivate (URL и маршрут еще не поменялись, поэтому не могу получить его ни через $ inject, ни через $ rootRouter)
  2. Я не могу найти способ передачи данных из $ canActivate в контроллер.
  3. Я не могу перенаправить из $canActivate (используя $rootRouter.navigate()).

    import template from './machine-details.html';
    
    export const machineDetailsComponent = {
        template: template,
        controller: machineDetailsController,
        $canActivate: canActivate,
    };
    
    /*@ngInject*/
    function machineDetailsController (machineDetailsService) {
        this.$routerOnActivate = function (nextRoute) {
            // do something;
        };
    }
    
    /*@ngInject*/
    function canActivate ($q, $rootRouter, machineDetailsService) {
        const deferred = $q.defer();
        /**
         * ISSUE 1:
         * if I get here via ng-link, then $rootRouter.lastNavigationAttempt 
         * shows the route I was on when clicking, however if I type the url manually 
         * (or refresh) I get something I can use which is for example '/machineDetails/c6bd76947fc01'
         **/ 
        const machineId = $rootRouter.lastNavigationAttempt.split('/')[2];
    
        machineDetailsService.getMachineDetailsData(machineId)
            .then(successHandler, errorHandler);
    
        /**        
         * ISSUE 2:
         * 'result' does not make its way into controller so I need to call
         * machineDetailsService.getMachineDetailsData again in controller...
         **/ 
        function successHandler (result) {
            deferred.resolve(); // passing on result has no affect
        }
    
        function errorHandler (error) {
            deferred.resolve(error);
            /** 
             * ISSUE 3: 
             * $rootRouter.navigate doesn't work here (and controller is 
             * never called) so how do I cause system to go back to list view ?
            **/ 
            // $rootRouter.navigate(['ListView']);
        }
    
        return deferred.promise;
    }
    

    Приведенный выше код является моим определением компонента, написанным на ES6.

1 ответ

Решение
  1. Вы можете ввести $nextInstruction в вашем $canActivate крюк, а затем вы можете получить доступ к своим параметрам через $nextInstruction.params,

    function canActivate($nextInstruction, $q, $rootRouter, machineDetailsService) {
      const machineId = $nextInstruction.params.id;
    }
    
  2. Я столкнулся с той же проблемой, но не смог найти решение для передачи данных из $canActivate подключиться к контроллеру.

  3. Вы можете перейти к ListView с помощью $rootRouter.navigate(['/ListView']), Обратите внимание на косую черту. Это должно быть указано, потому что ваш ListView это не детский маршрут.

Другие вопросы по тегам