Angular UI Router - просмотр в унаследованном состоянии

изменить: На основе ответа от @actor2019 я хочу обновить свой вопрос, чтобы лучше объяснить проблему:

Используя Angular UI-Router (v0.0.2), я настроил приложение, чтобы правильно перемещаться между основными "страницами", /state, наследуя базовое состояние.

Index.html:

<div ui-view></div>

base.html:

<!-- Header -->
<div>
    <!-- Header markup -->

    <!-- Search View -->
    <div ui-view="search"></div>
</div>

<!-- Page Content view -->
<div ui-view></div>

Проблема находится здесь, в файле app.js. Когда я добавляю параметр views в состояние base, все перестает работать (100% пустая страница). Без этого параметра страница отображается правильно, но у меня нет вида поиска.

app.js:

$urlRouterProvider.otherwise('/');

//
// Now set up the states
$stateProvider
  .state('base', {
    abstract: true,
    templateUrl: 'views/base.html',
    views: {
      "search": {
        templateUrl: "views/search.html"
      }
    }
  })
  .state('base.home', {
    url: "/",
    templateUrl: "views/home.html"
  })
  .state('base.page2', {
    url: "/page2",
    templateUrl: "views/page2.html"
  });

Как добавить представления в это базовое состояние родителя?

enter image description here

UPDATE: Проблема с @actor2019 answer здесь заключается в том, что представление search становится повторно инициализированным при изменении состояния. Я бы хотел, чтобы представления с базового уровня сохранялись через изменения состояния.

Ответы

Ответ 1

Первая очевидная ошибка:

Вы не можете указать контроллер и шаблон в состоянии во время использования представлений. Они являются взаимоисключающими...

Это связано с тем, что, когда в состоянии нет "представлений", кроме контроллера и шаблона, UI-Router автоматически создает свойство "views" и переносит эти свойства в "пустой" вид...

.state('base', {
  abstract: true,
  templateUrl: 'views/base.html', //Can't do this
  views: { // when this is there.
    "search": {
      templateUrl: "views/search.html"
    }
  }
})

Вместо этого выполните:

.state('base', {
  abstract: true,
    views: {
      "": {
        templateUrl: 'views/base.html'
      },
      "search": {
        templateUrl: "views/search.html"
      }
    }
  })

Вторая проблема:

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

Способ отображения в UI-маршрутизаторе - худшая часть UI-маршрутизатора...

Учитывая пример, я даже не совсем уверен в том, как настроить таргетинг на представление поиска из вашего абстрактного родительского состояния... Может быть:

.state('base', {
  abstract: true,
    views: {
      "": {
        templateUrl: 'views/base.html'
      },
      "[email protected]": {
        templateUrl: "views/search.html"
      }
    }
  })

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

Вся концепция представления является самой большой причиной, по которой я в конечном итоге написал https://github.com/dotJEM/angular-routing.

Ответ 2

Состояние ребенка должно быть home.search вместо header.search. В вашем случае вы можете написать некоторое состояние abstract, чтобы сохранить макет,

base.html

<div class="row-fluid">
    <div class="header">
        <div class="span3" ui-view="logo"></div>
        <div  class="span9" ui-view="menu"></div>
    </div>
</div>

<div class="row-fluid">
    <div class="content">
        <div class="span2" ui-view="sidebar"></div>
        <div  class="span10" ui-view="entry"></div>
    </div>
</div>

в app.js

$stateProvider
    .state('base',{
        abstract:true,
        url:'/',
        templateUrl: viewBase+'base.html'
    })
    .state('base.main',{
        url:'',
        views:{
            "logo":{
                templateUrl:viewBase+'main/logo.html'
            },
            "menu":{
                templateUrl:viewBase+'main/menu.html'
            },
            "sidebar":{
                templateUrl:viewBase+'main/sidebar.html'
            },
            "entry":{
                templateUrl: viewBase+'main/entry.html'
            }
        }})

Ответ 3

Согласно документации ui-router , когда приложение находится в определенном состоянии - когда состояние является "активным" - все его государства-предки также неявно активны. Так, например, когда состояние "contacts.list" активно, состояние "контакты" также неявно активно, потому что это родительское состояние "contacts.list". Статусы детей загружают свои шаблоны в их родительский ui-view. Я бы рекомендовал просмотреть раздел документации под названием Вложенные государства и представления, чтобы получить более полное представление о том, как сделайте это.

В коде, который вы нам предоставили, родительское состояние шаблона поиска home, а

.state('header.search', {
    templateUrl: "views/search.html",
    controller: "SearchCtrl"
})

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

app.js

$stateProvider
  .state('home', {
    url: "/",
    views: {
      '': {
        templateUrl: "views/mainContent.html",
        controller: "MainCtrl"
      },
      'header': {
        templateUrl: "views/header.html"
      },
      'footer': {
        templateUrl: "views/footer.html"
      },
    }
  })
  .state('home.search', {
    views: {
      'search': {
        templateUrl: "views/search.html",
        controller: "SearchCtrl"
      }
  })
  .state('anotherPage', {
    url: "/anotherPage",
    templateUrl: "views/anotherPage.html"
  });

Ответ 4

Это работает для меня.

$stateProvider
    .state('base', {
      abstract: true,
      url:'/',
      templateUrl: 'views/base.html'
    })
    .state('base.home', {
      url: "",
      views: {
      "[email protected]": {
        templateUrl: "views/searchOfHome.html"
      }
      //[email protected], contentOfHome.html
    }
    })
    .state('base.page2', {
      url: "page2",
      views: {
      "[email protected]": {
        templateUrl: "views/searchOfPage2.html"
      }
      //[email protected], contentOfPage2.html
    });

Если 'base' является корневым состоянием, вам не нужно '@base'