Переспрямуйте стан на підстанцію за замовчуванням за допомогою UI-Router у AngularJS


89

Я створюю сторінку на основі вкладки, на якій відображаються деякі дані. Я використовую UI-маршрутизатор в AngularJs для реєстрації станів.

Моя мета - відкрити одну вкладку за замовчуванням при завантаженні сторінки. На кожній вкладці є підвкладки, і я хотів би мати відкриту підвкладку за замовчуванням при зміні вкладок.

Я тестував за допомогою onEnterфункції, і всередині я використовую, $state.go('mainstate.substate');але, здається, це не працює через проблеми з ефектом циклу (на state.go до substate він викликає свій батьківський стан і так далі, і він перетворюється на цикл).

$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'}
})

Тут я створив демо-версію plunker .

На даний момент все працює, за винятком того, що у мене не відкрита вкладка за замовчуванням, і це саме те, що мені потрібно.

Дякуємо за ваші пропозиції, думки та ідеї.

Відповіді:


172

Оновлення: 1.0 і далі Підтримує переспрямуванняНезалежно

https://ui-router.github.io/ng1/docs/latest/interfaces/state.statedeclaration.html#redirectto


Я створив тут приклад .

Це рішення походить від приємного "Коментару" до проблеми з переспрямуванням за допомогою .when() ( https://stackoverflow.com/a/27131114/1679310 ) і справді крутого рішення для нього (Кріс Т, але оригінальний допис був yahyaKacem)

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

Отже, по-перше, давайте розширимо 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 для збереження історії браузера.


4
Здається, це забиває кнопку "Назад".
Scott Sword

6
@ Swordfish0321, щоб виправити кнопку "Назад", внесіть цю невелику зміну: $state.go(to.redirectTo, params, {location: 'replace'});Це призведе до того, що новий стан замінить попередній стан (тобто той, з якого ми переспрямовуємо) в історії. Див. Документи для $ state.go: angular-ui.github.io/ui-router/site/#/api/…
Алек,

2
Просто хотів додати, що це було дуже близько до того, що я хотів зробити, але я хотів, щоб URL-адреса за замовчуванням замінювала її, це легко було зробити, змінивши '$stateChangeStart'на'$stateChangeSuccess'
Матті Прайс

6
ui-router 1.0 вбудував для цього підтримку: ui-router.github.io/guide/ng1/…
Герт,

21

Насправді, навіть якщо це рішення, запропоноване Радімом, виконувало саме ту роботу, мені потрібно було пам'ятати про кожну вкладку (вкладку).

Тож я знайшов інше рішення, яке робить те саме, але також пам’ятає кожну підстанцію вкладок.

Мені все потрібно було встановити ui-router-extras та використовувати функцію глибокого перенаправлення стану :

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

Дякую!


12

Станом на версію 1.0 ui-маршрутизатора він підтримує redirectToвластивість. Наприклад:

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

7

Починаючи з версії 1.0 інтерфейсу ui-router, було введено перемикач за замовчуванням за допомогою IHookRegistry.onBefore (), як продемонстровано у прикладі Data Driven Default Substate у http://angular-ui.github.io/ui-router/feature-1.0/ інтерфейси / перехід.ihookregistry.html # onbefore

// 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);
});

Цей вид роботи для мене, хоча мені довелося його налаштувати (також використовуючи ES6)$transitions.onBefore({ to: state => state.defaultSubstate != null }, trans => trans.router.stateService.target(trans.to().defaultSubstate));
yorch

3
app.config(function($stateProvider,$urlRouterProvider){

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

    })

1
Чи можете ви пояснити, що це робить, і чому це краще, ніж уже існуючі відповіді?
Equalsk

Це рішення є найпростішим і добре працювало для мене.
BuffMcBigHuge

Це найкраща відповідь на сьогодні. Більш стислий, ніж використання подій змін. Не потрібно додавати пакети. Я не знаю, як це нікому не зрозуміло. Я не знаю, як прийнята відповідь так сильно проголосувала.
CodeWarrior

1

Якщо хтось приходить сюди для відповіді щодо того, як реалізувати просте перенаправлення для штату, і, як це сталося зі мною, не має можливості використовувати новий маршрутизатор ...

Очевидно ще раз, якщо можете, відповідь @bblackwo чудова:

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

Якщо ви не можете, просто перенаправіть його вручну:

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

Сподіваюся, це допоможе!

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.