Я начал с Angular 2+, но в моей нынешней компании есть несколько проектов, для которых требуется AngularJS 1x. Итак, мы здесь!

В этом посте я покажу вам, как обрабатывать маршрутизацию AngularJS 1x с помощью UI-Router. В другом посте я буду использовать Angular-Route (ngRoute) для обработки маршрутизации AngularJS.

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

Если вы хотите узнать больше о различиях между ними, проверьте этот поток из stackoverflow.

Версия AngularJS, которую я использовал в этом посте, - 1.7.2, она может отличаться, если вы используете более старые версии.

Версия UI-Router, которую я использую в этом посте, - v1.0.19.

Перед тем как начать, вы можете взглянуть на проект от Plunker.



Запустите проект AngularJS

Создать проект AngularJS легко, вам просто нужно встроить файлы angular в голову.

// index.html
<html ng-app="angularRouting">
...
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.7.2/angular.min.js"></script>
<script src="https://unpkg.com/@uirouter/[email protected]/release/angular-ui-router.min.js"></script>
<script src="app.js"></script>
...
// Navigation Menu
<ul class="uk-nav uk-nav-default">
 <li class="uk-active">
  <a ui-sref="home">Menu</a>
 </li>
 <li>
  <a ui-sref="home" ui-sref-active="active">Home</a>
 </li>
 <li>
  <a ui-sref="about" ui-sref-active="active">About</a>
 </li>
</ul>
// Content will go here
<ui-view></ui-view>

Ваша основная логика будет в app.js.

var app = angular.module('angularRouting', ['ui.router']);

Давайте наладим маршрутизацию

Нам нужно добавить $ stateProvider, чтобы управлять маршрутизацией. В приведенном ниже коде показана маршрутизация для домашней страницы и страницы с информацией о компании. Вы можете протестировать его прямо сейчас в своем браузере.

В противном случае с $ urlRouterProvider перенаправит все остальные маршруты на домашнюю страницу. На практике вы покажете шаблон 404 для этого. Вы можете заменить template на tempateUrl, если хотите отделить HTML-шаблон.

// app.js
app.config(function($stateProvider, $urlRouterProvider){
  var states = [
    {
      name: 'home',
      url: '/',
      template: '<h1>This is home</h1>'
    },
    {
      name: 'about',
      url: '/about',
      template: '<h1>This is about</h1>'
    }
  ];
  states.forEach((state) => $stateProvider.state(state));
  $urlRouterProvider.otherwise('/');
});

Получить параметры из URL

Я создал меню с параметром. В вашем приложении параметр будет заполняться динамически через {{id}}. В этом примере я буду использовать номер 1 в качестве дополнительного параметра для маршрута params.

// index.html
<ul class="uk-nav uk-nav-default">
 <li class="uk-active">
  <a ui-sref="home">Menu</a>
 </li>
 <li>
  <a ui-sref="home" ui-sref-active="active">Home</a>
 </li>
 <li>
  <a ui-sref="about" ui-sref-active="active">About</a>
 </li>
 <li>
  <a ui-sref="params({id: 1})" ui-sref-active="active">Params</a>
 </li>
</ul>

Теперь нам нужно настроить маршрутизацию в app.js. Я буду использовать ParamsController, чтобы получить параметр и показать его в шаблоне.

// app.js
app.config(function($stateProvider, $urlRouterProvider){
  var states = [
    {
      name: 'home',
      url: '/',
      template: '<h1>This is home</h1>'
    },
    {
      name: 'about',
      url: '/about',
      template: '<h1>This is about</h1>'
    },
    {
      name: 'params',
      url: '/params/{id}',
      template: '<h1>Param value: {{ paramId }}</h1>',
      controller: function($scope, $stateParams) {
        $scope.paramId = $stateParams.id;
      }
    }
  ];
  states.forEach((state) => $stateProvider.state(state));
  $urlRouterProvider.otherwise('/');
});

Как охранять свой маршрут

Итак, есть страницы, которые вы не хотите показывать публике. Пользователь должен войти в систему, чтобы просмотреть их.

// index.html
<ul class="uk-nav uk-nav-default">
 <li class="uk-active">
  <a ui-sref="home">Menu</a>
 </li>
 <li>
  <a ui-sref="home" ui-sref-active="active">Home</a>
 </li>
 <li>
  <a ui-sref="about" ui-sref-active="active">About</a>
 </li>
 <li>
  <a ui-sref="params({id: 1})" ui-sref-active="active">Params</a>
 </li>
 <li>
  <a ui-sref="auth" ui-sref-active="active">You shall not pass!</a>
 </li>
</ul>
{{ message }} //show authentication message
<main ng-view></main>

Затем вы добавите сервис маршрутизации и аутентификации в app.js. Если у пользователя нет разрешения на просмотр страницы, он будет перенаправлен на главную страницу.

Мы воспользуемся преимуществами Transition Hooks для управления маршрутизацией.

// app.js
// Handle authentication error
app.run(['$rootScope', '$transitions', '$state', '$trace', function($rootScope, $transitions, $state, $trace){
  $transitions.onError({}, function(transition) {        
    if(transition.to().name === 'auth' && transition.error().detail === 'AUTH_REQUIRED') {
      $rootScope.message = 'You need to login in order to view that page!';
        $state.go('home');
    }
  });
}]);
app.config(function($stateProvider, $urlRouterProvider){
  var states = [
    {
      name: 'home',
      url: '/',
      template: '<h1>This is home</h1>'
    },
    {
      name: 'about',
      url: '/about',
      template: '<h1>This is about</h1>'
    },
    {
      name: 'params',
      url: '/params/{id}',
      template: '<h1>Param value: {{ paramId }}</h1>',
      controller: function($scope, $stateParams) {
        $scope.paramId = $stateParams.id;
      }
    },
    {
      name: 'auth',
      url: '/auth',
      template: '<h1>Success</h1>',
      resolve: {
        auththenticate: ['$q', function($q) {
          if(true) { // user is not logged in
            return $q.reject("AUTH_REQUIRED");
          }
        }]
      }      
    }
  ];
  states.forEach((state) => $stateProvider.state(state));
  $urlRouterProvider.otherwise('/');
});

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

Теперь вы знаете, как обрабатывать маршрутизацию AngularJS с помощью UI-Router. Вы также можете использовать Angular-Route (ngRoute) для управления своими маршрутами.

Надеюсь это поможет :)