Липкие состояния реинициализируют контроллер

У меня проблемы с реализацией закрепленных вкладок, где каждая вкладка может иметь несколько дочерних состояний, используя ui-router-tabs и ui-router-extras.

  1. Когда я открываю состояние, перехожу на другое, а затем возвращаюсь в первое состояние, соответствующий контроллер переинициализируется (хотя вывод отладки ui-router-extras говорит, что он активировал состояние)

  2. Когда я открываю другое состояние той же вкладки (состояние родного брата), выходные данные отладки, URL-адрес и запрос шаблона html говорят мне, что новое состояние загружено, но на вкладке отображается пустой контент и вызов API государство не выполнено

Это мое состояние / конфигурация маршрута:

$stateProvider
      .state('home', {
        url: '/',
        templateUrl: 'modules/core/views/home.client.view.html'
      })
      .state('home.feed', {
        abstract: true,
        url: '',
        template: '<div ui-view="list" ng-show="$state.includes(\'home.feed.list\')"/>'+
                  '<div ui-view="view" ng-show="$state.includes(\'home.feed.view\')"/>'+
                  '<div ui-view="profile" ng-show="$state.includes(\'home.feed.profile\')"/>',
        data: {
          roles: ['user', 'admin']
        },
        sticky: true,
        deepStateRedirect: true
      })
      .state('home.feed.list', {
        url: 'posts',
        views: {
          'list@home.feed': {
            templateUrl: 'modules/posts/views/list-feed.client.view.html'
          }
        },
        sticky: true
      })
      .state('home.feed.view', {
        url: 'posts/:postId',
        views: {
          'view@home.feed': {
            templateUrl: 'modules/posts/views/view-post.client.view.html'
          }
        },
        sticky: true
      })
      .state('home.create', {
        abstract: true,
        url: '',
        template: '<div ui-view="form" ng-show="$state.includes(\'home.create.form\')"/>',
        data: {
          roles: ['user', 'admin']
        },
        sticky: true,
        deepStateRedirect: true
      })
      .state('home.create.form', {
        url: 'create',
        views: {
          'form': {
            templateUrl: 'modules/posts/views/create-post.client.view.html'
          }
        },
        sticky: true
      });

"Домашнее" состояние содержит пользовательский интерфейс для всех вкладок, а также панель навигации. Каждое абстрактное состояние представляет одну вкладку и содержит именованные представления для всех своих дочерних состояний. 3-й уровень состояний (например, home.feed.list) представляет фактический контент.

//home
<div data-ng-controller="HomeController">

  <ui-view></ui-view>

  <div class="navbar navbar-fixed-bottom">
    <tabs data="tabData" type="tabs" justified="true" template-url="modules/core/views/custom-tab-template.client.view.html"></tabs>
  </div>

</div>

//home.feed.list
<section data-ng-controller="PostsController" data-ng-init="loadPosts()">
...
</section>

//home.feed.view
<section data-ng-controller="PostsController" data-ng-init="findOne()">
...
</section>

//home.create.form
<section data-ng-controller="PostsController">
...
</section>

Представления используют один и тот же контроллер, но я уже пытался добавить отдельный контроллер для каждого представления. Кроме того, я попытался удалить вкладки ui-router и назвал состояния по URL, тот же результат.

Пример выходных данных отладки для: home.feed.list -> home.create.form -> home.feed.list (из-за недостаточной репутации для публикации фотографий)

Current transition:  : {}:  -> home.feed.list: {}
Before transition, inactives are:   :  []
After transition,  inactives will be:  []
Transition will exit:   []
Transition will enter:  ["ENTER: home", "ENTER: home.feed", "ENTER: home.feed.list"]
SurrogateFromPath:  []
SurrogateToPath:    ["home", "home.feed", "home.feed.list"]
I am initializing PostsController
Current state: home.feed.list, inactive states:  []
Views: (__inactives.locals) / (root.locals) / (home.locals: '@' (home)) / (home.locals: '@' (home)) / (home.feed.locals: '@home' (home.feed)) / (home.feed.list.locals: 'list@home.feed' (home.feed.list))
Current transition:  home.feed.list: {}:  -> home.create.form: {}
Before transition, inactives are:   :  []
After transition,  inactives will be:  ["home.feed", "home.feed.list"]
Transition will exit:   ["(home)", "INACTIVATE: home.feed", "INACTIVATE: home.feed.list"]
Transition will enter:  ["(home)", "ENTER: home.create", "ENTER: home.create.form"]
SurrogateFromPath:  ["home", "inactivate:home.feed", "inactivate:home.feed.list"]
SurrogateToPath:    ["home", "home.create", "home.create.form"]
I am initializing PostsController
Current state: home.create.form, inactive states:  ["home.feed.list", "home.feed"]
Views: (__inactives.locals: '@home' (home.feed), 'list@home.feed' (home.feed.list)) / (root.locals) / (home.locals: '@' (home)) / (home.locals: '@' (home)) / (home.create.locals: '@home' (home.create)) / (home.create.form.locals: 'form@home.create' (home.create.form))
Current transition:  home.create.form: {}:  -> home.feed.list: {}
Before transition, inactives are:   :  ["home.feed.list", "home.feed"]
After transition,  inactives will be:  ["home.create", "home.create.form"]
Transition will exit:   ["(home)", "INACTIVATE: home.create", "INACTIVATE: home.create.form"]
Transition will enter:  ["(home)", "REACTIVATE: home.feed", "REACTIVATE: home.feed.list"]
SurrogateFromPath:  ["home", "reactivate_phase1:home.feed", "reactivate_phase1:home.feed.list", "inactivate:home.create", "inactivate:home.create.form"]
SurrogateToPath:    ["home", "reactivate_phase1:home.feed", "reactivate_phase1:home.feed.list", "reactivate_phase2:home.feed", "reactivate_phase2:home.feed.list"]
I am initializing PostsController
Current state: home.feed.list, inactive states:  ["home.create.form", "home.create"]
Views: (__inactives.locals: '@home' (home.create), 'form@home.create' (home.create.form)) / (root.locals) / (home.locals: '@' (home)) / (home.locals: '@' (home)) / (home.feed.locals: '@home' (home.feed)) / (home.feed.list.locals: 'list@home.feed' (home.feed.list))

Тот же вывод генерируется, когда я использую 3 разных контроллера ("Я инициализирую.." выполняется на каждом контроллере).

1 ответ

Я нашел ошибки:

  1. Потому что второй уровень состояний (home.feed и home.create) должен быть липким, а также им нужен именованный родительский пользовательский интерфейс. Я забыл изменить одно представление ui внутри home-html на два имени ui-views.

И, конечно, мне пришлось адаптировать определения состояний:

.state('home.feed', {
        url: '',
        views: {
          'feed@home': {
            template: '<div ui-view="list" ng-show="$state.includes(\'home.feed.list\')"></div>'+
            '<div ui-view="view" ng-show="$state.includes(\'home.feed.view\')"></div>'+
            '<div ui-view="profile" ng-show="$state.includes(\'home.feed.profile\')"></div>'
          }
        },
        data: {
          roles: ['user', 'admin']
        },
        sticky: true,
        deepStateRedirect: {
          default: { state: "home.feed.list" }
        }
      })
      .state('home.create', {
        abstract: true,
        url: '',
        views: {
          'create@home': {
            template: '<div ui-view="form" ng-show="$state.includes(\'home.create.form\')"></div>'
          }
        },
        data: {
          roles: ['user', 'admin']
        },
        sticky: true,
        deepStateRedirect: true
      })
  1. Эта проблема была вызвана использованием div с включенным закрывающим тегом. Я изменил это на стандартное определение со стартовым и закрывающим тегом (разница с определением шаблона выше).
Другие вопросы по тегам