Перенаправить состояние в подсостояние по умолчанию с помощью UI-Router в AngularJS

Я создаю вкладку на основе страницы, которая показывает некоторые данные. Я использую UI-Router в AngularJs для регистрации состояний.

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

Я тестировал с onEnter функция и внутри я использую $state.go('mainstate.substate'); но, похоже, он не работает из-за проблем с эффектом петли (при state.go для его подстановки он вызывает родительское состояние и т. д., и он превращается в цикл).

$stateProvider

.state('main', {
  url: '/main',
  templateUrl: 'main.html',
  onEnter: function($state) {
    $state.go('main.street');
  }
})

.state('main.street', {
  url: '/street',
  templateUrl: 'submenu.html',
  params: {tabName: 'street'}
})

Здесь я создал демо-версию плунжера.

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

Спасибо за ваши предложения, мнения и идеи.

6 ответов

Решение

Я создал пример здесь.

Это решение приходит из приятного "комментария" к проблеме с перенаправлением с помощью .when() ( /questions/19867487/angular-ui-router-urlrouterprovider-kogda-ne-rabotaet-kogda-ya-nazhimayu-a-ui-sref/19867496#19867496) и действительно классное решение для него (Крис Т, но оригинальный пост был от yahyaKacem)

https://github.com/angular-ui/ui-router/issues/1584

Итак, во-первых, давайте расширим main настройкой перенаправления:

$stateProvider
    .state('main', {
      url: '/main',
      templateUrl: 'main.html',
      redirectTo: 'main.street',
    })

И добавить только эти несколько строк в бег

app.run(['$rootScope', '$state', function($rootScope, $state) {

    $rootScope.$on('$stateChangeStart', function(evt, to, params) {
      if (to.redirectTo) {
        evt.preventDefault();
        $state.go(to.redirectTo, params, {location: 'replace'})
      }
    });
}]);

Таким образом, мы можем настроить любое из наших состояний с помощью перенаправления по умолчанию... Проверьте это здесь

РЕДАКТИРОВАТЬ: Добавлена ​​опция из комментария @Alec для сохранения истории браузера.

На самом деле, даже если это решение, предложенное Radim Köhler, выполняло именно эту работу, мне нужно было помнить каждую вкладку (состояние).

Поэтому я нашел другое решение, которое делает то же самое, но также запоминает каждое подсостояние вкладок.

Все, что мне нужно сделать, - это установить дополнительные элементы ui-router и использовать функцию перенаправления глубокого состояния:

$stateProvider
  .state('main.street', {
     url: '/main/street',
     templateUrl: 'main.html',
     deepStateRedirect: { default: { state: 'main.street.cloud' } },
  });

Спасибо!

Начиная с версии 1.0 UI-маршрутизатора он поддерживает redirectTo имущество. Например:

.state('A', {
  redirectTo: 'A.B'
})

Начиная с версии 1.0 ui-router, ловушка по умолчанию была введена с использованием IHookRegistry.onBefore(), как показано в примере управляемой данными подсистемы по умолчанию в http://angular-ui.github.io/ui-router/feature-1.0/interfaces/transition.ihookregistry.html

// state declaration
{
  name: 'home',
  template: '<div ui-view/>',
  defaultSubstate: 'home.dashboard'
}

var criteria = {
  to: function(state) {
    return state.defaultSubstate != null;
  }
}
$transitions.onBefore(criteria, function($transition$, $state) {
  return $state.target($transition$.to().defaultSubstate);
});
app.config(function($stateProvider,$urlRouterProvider){

    $urlRouterProvider.when("/state","/state/sub-state");

    })

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

Очевидно, если можно, ответ @bblackwo великолепен:

$stateProvider.state('A', {
  redirectTo: 'B',
});

Если вы не можете, просто перенаправьте его вручную:

$stateProvider.state('A', {
  controller: $state => {
    $state.go('B');
  },
});

Я надеюсь, что это помогает!

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