Множественный просмотр, в котором один будет меняться в зависимости от состояния или URL, а другие останутся прежними [Angular UI Router]

#angularjs #angular-ui-router

#angularjs #angular-ui-router

Вопрос:

Я пытаюсь создать блог для себя, используя Angular и ASP.NET Веб-API. Вот мой Layout.cshtml

 <div id="header">
    <div data-ui-view="menu"></div>
</div>
<div id="main">
    <div data-ui-view></div>
    <div data-ui-view="sidebar"></div>
</div>
<div id="footer">
    <div data-ui-view="footer"></div>
</div>
  

И просмотры с помощью text/ng-template

 <!-- Layout Views -->
<script type="text/ng-template" id="/Templates/Layout/Menu.html">
   <div>
     <a ui-sref="home">Home</a>
     <a ui-sref="register">Register</a>
</script>

<script type="text/ng-template" id="/Templates/Layout/Sidebar.html">
   <div>Sidebar</div>
</script>

<script type="text/ng-template" id="/Templates/Layout/Footer.html">
   <div>Footer</div>
</script>

<!-- Page Views -->
<script type="text/ng-template" id="/Templates/Layout/Home.html">
   <div>Home</div>
</script>

<script type="text/ng-template" id="/Templates/Layout/Register.html">
   <div>Register</div>
   <a ui-sref="home">Back</a>
</script>
  

И вот app.js

 angular.module('app', ['ui.router'])
  .config(['$stateProvider', '$urlRouterProvider', 
      function($stateProvider, $urlRouterProvider) {
        $urlRouterProvider.otherwise('/');

        $stateProvider
           .state('home', {
                url: '/',
               views: {
                 '': {
                   templateUrl: '/Templates/Layout/Home.html'
                 },
                 'menu@': {
                   templateUrl: '/Templates/Layout/Menu.html'
                 },
                 'sidebar@': {
                   templateUrl: '/Templates/Layout/Sidebar.html'
                 },
                 'footer@': {
                   templateUrl: '/Templates/Layout/Footer.html'
                 }
               }
           }).state('register', {
               url: '^/Register',
               templateUrl: '/Templates/Layout/Register.html'
        });
  }]);
  

Вот что я хочу:

  1. Когда я просматриваю домашнюю страницу (domain/#/) , он заменит неназванный вид на Home.html
  2. Когда я просматриваю страницу регистрации (domain/#/Register) или нажимаю Register из меню, он заменит неназванный просмотр на Register.html

На данный момент domain/#/ работает нормально, но (domain/#/Register) показывает Register только вид, тогда как он должен был показывать и другие 3 вида (меню, боковая панель, нижний колонтитул).

ССЫЛКА на CODEPEN

Я проверяю stackoverflow amp; разные блоги в течение 2 дней, но не могу решить проблему. Чего мне здесь не хватает? Любая помощь будет оценена.

Ответ №1:

Один из способов добиться этого — создать абстрактное состояние «master», в котором вы определяете шаблоны для именованных представлений, а затем «дочерние элементы» этого «master» для вашего home и register состояний. Вот пример, адаптированный непосредственно из вашего Codepen:

 angular.module('app', ['ui.router'])
  .config(['$stateProvider', '$urlRouterProvider',
    function($stateProvider, $urlRouterProvider) {
      $urlRouterProvider.otherwise('/');
      $stateProvider
        .state('master', {
          abstract: true,
          views: {
            'menu@': {
              templateUrl: '/Templates/Layout/Menu.html'
            },
            'sidebar@': {
              templateUrl: '/Templates/Layout/Sidebar.html'
            },
            'footer@': {
              templateUrl: '/Templates/Layout/Footer.html'
            }
          }
        })
        .state('master.home', {
          url: '/',
          views: {
            '@': {
              templateUrl: '/Templates/Layout/Home.html'
            }
          }


        }).state('master.register', {
          url: '/Register',
          views: {
            '@': {
              templateUrl: '/Templates/Layout/Register.html'
            }
          }

        });
    }
  ]);  
 <script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.4.3/angular.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular-ui-router/0.2.15/angular-ui-router.min.js"></script>

<body ng-app="app">
  <div id="header">
    <div data-ui-view="menu"></div>
  </div>
  <div id="main">
    <div data-ui-view></div>
    <div data-ui-view="sidebar"></div>
  </div>
  <div id="footer">
    <div data-ui-view="footer"></div>
  </div>

  <!-- Layout Views-->
  <script type="text/ng-template" id="/Templates/Layout/Menu.html">
    <div>
      <a ui-sref="master.home">Home</a>
      <a ui-sref="master.register">Register</a>
    </div>
  </script>

  <script type="text/ng-template" id="/Templates/Layout/Sidebar.html">
    <div>Sidebar</div>
  </script>

  <script type="text/ng-template" id="/Templates/Layout/Footer.html">
    <div>Footer</div>
  </script>

  <!-- Page Views-->
  <script type="text/ng-template" id="/Templates/Layout/Home.html">
    <div>Home</div>
  </script>

  <script type="text/ng-template" id="/Templates/Layout/Register.html">
    <div>Register</div>
    <a ui-sref="master.home">Back</a>
  </script>
</body>  

Комментарии:

1. Спасибо. Это работа для меня. Я действительно хочу что-то вроде этого.

Ответ №2:

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

Вам нужно внести два изменения:

Определите register как дочернее состояние home :

 .state('home.register', {
    url: 'Register',
    views: {
        '@': {
            templateUrl: '/Templates/Layout/Register.html'
        }
    }
  

Обновите ui-sref в меню:

 <script type="text/ng-template" id="/Templates/Layout/Menu.html">
    <div>
        <a ui-sref="home">Home</a>
        <a ui-sref="home.register">Register</a>
    </div>
</script>
  

Рабочий Codepen

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

Ответ @ Lex на то, чтобы иметь базовое состояние master / root / layout, также действительно хорош и хорошо работает в более сложных ситуациях. Мой ответ очень прост, минимум, чтобы заставить ваш код работать.

Комментарии:

1. Спасибо. Ваш ответ работает для меня с минимальным изменением моего кода. Но на будущее я буду использовать ответ @ Lex.