Angular 1.5 $routerOnActivate на Root Router

Я хочу убедиться, что пользователь вошел в систему должным образом, прежде чем переходить к любому из компонентов, к которым он / она пытается обратиться, если они не вошли в систему. Отправьте его для входа.

Моя идея сделать проверку в $routerOnActivate в корневом роутере. Который для меня решит проблему для любых суб-маршрутов.

Однако ничего не происходит, если я просто пытаюсь что-то записать. Пример:

angular
    .module('app')
    .config(function($locationProvider) {
        $locationProvider.html5Mode(true);
    })
    .value('$routerRootComponent', 'app')
    .component('app', {
          templateUrl:'landing.html',
          controller: MainController,
          $routeConfig: [
                { path: '/', name: 'Dashboard', component: 'dashboard', useAsDefault: true },
                { path: '/media', name: 'Media', component: 'media'}
                ...
          ]
    });


function MainController(){
    this.$routerOnActivate = function(next, previous){
        console.log('activated', next, previous);
    };
}

Тот же код this.$routerOnActivate работает, если я положу его в любой из компонентов, которые указаны в routeConfig. Однако, очевидно, я не хочу делать одну и ту же проверку в каждом компоненте, а скорее решить ее один раз в глобальном масштабе.

Какой подход для 1,5?

2 ответа

Решение

Вставить из моего комментария по запросу

А как насчет выполнения проверки на странице загрузки? Это будет отлично работать в angular.run.

И если вы хотите обработать истечение сеанса, вы можете добавить перехватчик для всех запросов и наблюдать за ответом 401.

Вместо выполнения проверки при загрузке страницы используйте следующее:

В Angular есть специальный хук жизненного цикла компонента для обработки этих краевых случаев, называемый $canActivate - проверить, стоит ли пытаться его активировать или нет. Вы можете поговорить со службой аутентификации / авторизации, чтобы проверить, разрешено ли для данного пользователя состояние вашего компонента или нет.

Таким образом, ваш компонент будет достаточно умен, чтобы инкапсулировать любые проверки, необходимые для его активации.

Кроме того, вы можете ввести любой сервис, как $http или ваш пользовательский сервис для общения с вашим сервером. В приведенном ниже фрагменте кода я имитирую этот вызов, используя $timeout это просто возвращает true, если вы вернете false, ваш компонент не будет активирован.

angular.module('app').component('someComponent', {
    template: 'this is an inline component template',
    $canActivate: function ($timeout) {
        return $timeout(function(){
            return true;
        }, 2000);
    }
}); 

Используйте другой крюк с именем $routerOnActivate читать следующий и предыдущий маршруты. Если вас интересуют параметры маршрута, используйте next.params который является объектом, который всегда будет иметь параметры, которые были переданы на этот маршрут. например next.params.id где id - это параметр, который был передан в запрошенный маршрут.

использование $canActivate используя TypeScript:

Я написал пост о том, как использовать компоненты AngularJS для записи в TypeScript, и у меня есть некоторые черновики для использования ловушек жизненного цикла маршрутизатора, которые я опубликую сегодня. Ниже приведен код для использования некоторых хуков с использованием TypeScript ниже:

class ReviewDetailsComponent implements ng.IComponentOptions {
        templateUrl = 'app/components/review-details.component.html';

        // function member for this hook doesn't work!!
        // so either use lambda expression or function directly.
        $canActivate = $timeout => $timeout(() => true, 3000);

        controllerAs = 'model';
        controller = ['$http', ReviewDetailsController];
    }

angular.module('app').component('reviewDetails', new ReviewDetailsComponent());

Код машинописного текста выше такой же, как фрагмент кода JavaScript выше, который использует $canActivate,

К сожалению, это не сработало, когда это определено как член функции в классе, как $canActivate() и сгенерированный javascript этот член определен с использованием прототипа, как ReviewDetailsComponent.prototype.$canActivate,

Но это хорошо работает, когда написано с использованием синтаксиса лямбда-выражений или функции напрямую. Если вы используете класс для определения компонента, в этом случае хорошо выбрать лямбда-выражение.

использование $routerOnActivate используя TypeScript

Связанный контроллер в этом случае также использует другой хук жизненного цикла с именем $routerOnActivate и это хорошо работает, если определено как член функции:

interface IReviewDetailsController {
    id: number;
    $routerOnActivate(next, previous);
}

class ReviewDetailsController implements IReviewDetailsController {

    id: number;

    constructor(private $http: angular.IHttpService) { }

    $routerOnActivate(next, previous) {
        this.id = next.params.id;

        // talk to cache or server to get item by id
        // & show that on UI
    }
}
Другие вопросы по тегам