Подтвердить что ты не робот

Как установить дочерний режим по умолчанию с помощью Angular UI Router

Скажем, у меня есть следующие 3 Angular UI Router:

$stateProvider
    .state('adminCompanies', {
        abstract: true,
        url: "/admin/companies",
        template: '<div ui-view class="viewContainer" autoscroll="false" />'
    })
    .state('adminCompanies.list', {
        url: "",
        templateUrl: 'app/admin/companies/companies.list.html',
        controller: 'AdminCompaniesController'
    })
    .state('adminCompanies.detail', {
        url: "/:companyId",
        templateUrl: 'app/admin/companies/companies.detail.html',
        resolve: {
            company: function(Model, $stateParams) {
                return Model.get("/admin/companies", $stateParams.companyId);
            }
        },
        controller: 'AdminCompanyDetailController'
    })

Если преобразование adminCompanies будет передано напрямую, как я могу определить Angular UI Router, чтобы перейти в состояние adminCompanies.list?

В идеале, я бы хотел что-то вроде:

$stateProvider.when('adminCompanies', 'adminCompanies.list');

В моем коде я хочу, чтобы $state.go('adminCompanies') был эквивалентен $state.go('adminCompanies.list')

4b9b3361

Ответ 1

Как только ваше приложение настроено, вам не нужна никакая явная логика для этого. Когда под-состояние имеет пустое свойство url, оно становится активным в то же время, когда его родительское состояние становится активным. Любой шаблон для под-состояния вставляется в директиву ui-view, предоставляемую шаблоном родительского состояния. Приложение Angular UI обращается к этому типу архитектуры: при навигации к состоянию contacts его шаблон предоставляет макет навигации, а также отдельный ui-view для своих под-состояний; потому что состояние contacts.list имеет свойство url "", оно автоматически загружается, когда его родительское состояние, contacts перемещается. Это описано в приложении комментарии:

Использование пустого URL означает, что это дочернее состояние станет активным при навигации по его родительскому URL. Адреса дочерних состояний автоматически добавляются к URL-адресам их родителя. Таким образом, этот URL-адрес состояния "/контакты" (потому что "/контакты" + '').

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

$stateProvider
    .state('adminCompanies', {
        abstract: true,
        url: "/admin/companies",
        template: '<div ui-view class="viewContainer" autoscroll="false" />'
    })
    .state('adminCompanies.list', {
        url: "/list",
        templateUrl: 'app/admin/companies/companies.list.html',
        controller: 'AdminCompaniesController'
    })
    .state('adminCompanies.detail', {
        url: "/:companyId",
        templateUrl: 'app/admin/companies/companies.detail.html',
        resolve: {
            company: function(Model, $stateParams) {
                return Model.get("/admin/companies", $stateParams.companyId);
            }
        },
        controller: 'AdminCompanyDetailController'
    })

Обратите внимание на добавление добавления abstract: true на третьей строке и явный URL-адрес состояния /list для adminCompanies.list

Это сообщает Angular -UI, что он должен рассматривать это состояние так, как будто оно не существует для целей навигации по URL. Он все равно станет активным, если вы перейдете к под-состояниям, поэтому он по-прежнему будет использовать указанный вами URL для префикса URL-адресов под-состояний. Но если вы попытаетесь перейти к нему из другого состояния, он будет действовать так, как будто состояние не существует. По этой причине вам также потребуется добавить обработку для неповторимых URL-адресов, используя $urlRouteProvider.

Основное использование $urlRouteProvider может выглядеть так:

$urlRouterProvider.otherwise("/")

Это просто перенаправляет все вызовы несуществующим состояниям в состояние с URL-адресом "/". Это предполагает, что у вас есть один. Однако, поскольку кто-то может попытаться перейти к представлению списка, но они непосредственно переходят к /admin/companies, вероятно, у вас должен быть такой обработчик:

$urlRouterProvider.when("/admin/companies", "/admin/companies/list");

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

Ответ 2

Вы также можете использовать ui-router-default - модуль, в котором дочерние состояния по умолчанию определены в родительском состоянии, установив abstract: ".defaultChild".

Это дает возможность использовать ui-sref="parent" и $state.go("parent"); (что было важно для меня при динамическом создании навигатора).

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

(См. также соответствующее обсуждение команды ui-router здесь.)

Ответ 3

В версии 1.0.0alpha0 они, наконец, делают это возможным! Не дочерний для абстрактных состояний, новый $transitionsProvider, в котором вы можете определить крюк onBefore. Вы можете изменить поведение, зависит от параметров состояния.

Например, вы можете изменить "абстрактное" поведение параметра:

 $transitionsProvider.onBefore({
    to: state => !!state.abstract
  }, ($transition$, $state) => {
    if (angular.isString($transition.to().abstract)) {
      return $state.target($transition.to().abstract);
    }
  });

и используйте его так:

  abstract: 'abstract2.foo',  //use not boolean but exact child state

пример кода

взят из: ui-router: дочерний элемент по умолчанию для абстрактного состояния