【问题标题】:How can I persist sibling ui-views when changing state?更改状态时如何保持同级 ui-views?
【发布时间】:2014-09-12 19:30:38
【问题描述】:

我的应用程序中有 2 个 ui-view 指令。一个包含子导航,另一个是实际的页面内容。我的子导航是一个树形结构,当您单击结束节点(或叶子)时,应该是内容视图唯一更新的时间。每当您单击子导航中的非叶子节点时,我希望内容视图在子导航视图更改时保持不变。

发生的情况是,每当我切换到未定义其中一个视图的状态时,视图就会被清除。我希望它保持在我改变状态之前的状态。有人做到了吗?

代码:

<!--NOTE THAT THESE ARE SIBLING ELEMENTS, NOT NESTED -->
<div id="subNav" ui-view="subNav"></div>
<div id="content" ui-view="content"></div>

这是我的路线设置。请注意,State1 仅应更新 subnav 视图,State2 应仅更新 content 视图。

$stateProvider
  .state('State1', {
    url: '/State1',
    views: {
      "subnav": { 
         templateUrl: "views/subnav.html",
         controller: "SubNavController"
      }
    }
  })
  .state('State2', {
    url: '/State2',
    views: {
      "content": { 
         template: "<p>State 2</p>"
      }
    }
  });

这是当前正在做的事情的 plnkr:http://plnkr.co/edit/TF7x5spB8zFLQPzrgZc9?p=preview

【问题讨论】:

    标签: javascript angularjs angularjs-routing angular-ui-router


    【解决方案1】:

    我想说,这里的路真的很明确:

    Multiple Named Views

    Nested States & Nested Views

    我正在使用这种技术,在非常相似的场景中:左列是一个列表,右列(大区域) 是一个细节的地方。有一个example

    状态定义为:

    $stateProvider
        .state('index', {
            url: '/',
            views: {
              '@' : {
                templateUrl: 'layout.html',
                controller: 'IndexCtrl'
              },
              'top@index' : { templateUrl: 'tpl.top.html',},
              'left@index' : { templateUrl: 'tpl.left.html',},
              'main@index' : { templateUrl: 'tpl.main.html',},
            },
          })
        .state('index.list', {
            url: '/list',
            templateUrl: 'list.html',
            controller: 'ListCtrl'
          })
        .state('index.list.detail', {
            url: '/:id',
            views: {
              'detail@index' : {
                templateUrl: 'detail.html',
                controller: 'DetailCtrl'
              },
            },
          })
    

    所以在我们的例子中,它可能是这样的:

    1. 父状态将具有两个状态(布局)的模板,并且还将注入导航栏
    2. 孩子只会将视图注入主区域

    父状态:

    .state('State1', {
        url: '/State1',
        views: {
          "bodyArea" { template: "body.thml"},
          "subnav@State1": { 
             templateUrl: "views/subnav.html",
             controller: "SubNavController"
          }
        }
    })
    

    所以我们可以看到,两种状态的模板,布局都定义在State1 上作为放置在“bodyArea”中的视图。

    另一个视图(原始)通过绝对名称“subnav@State1”注入到该模板中。 IE。为一个父状态定义了 2 个视图...

    子状态:

    .state('State2', {
        parent: 'State1', // a child needs parent
        url: '/State2',
        views: {
          "content": { 
             template: "<p>State 2</p>"
          }
        }
    })
    

    在这里,我们只是说,State1 是 State2 的父级。这意味着,“内容”目标/锚 (ui-view="content") 必须是 State1 中定义的视图的一部分。这里最好的地方是“body.html”...

    EXTEND:基于 cmets 和 this plunker 的一些问题,我创建了它的 updated version。 Main1 的导航已损坏(以便能够进行比较),但 Main2 和 Main3 正在工作。

    • Main2 正在工作,因为它的 def 与 index 状态相似
    • 另一方面,Main3index 状态的子节点

    从这个 sn-p 中应该清楚地知道实际的绝对和相对命名:

    索引:

    $stateProvider
      .state('index', {
        url: '/',
        views: {
          '@': {
            templateUrl: 'layout.html'
          },
          'mainNav@index': {
            template: '<a ui-sref="Main1">Main1</a><br />'
                    + '<a ui-sref="Main2">Main2</a><br />'
                    + '<a ui-sref="Main3">Main3</a>'
          },
          'subNav@index' : {
            template: '<p>This is the sub navigation</p>'
          }, 
          'content@index': {
            template: '<p>This is the content</p>'
          }
        }
      })
    

    有问题的 Main1

      .state('Main1', {
        url: '/Main1',
        views: {
          /*'mainNav': {
    
          },*/
          'subNav': {
            template: '<a ui-sref="Sub1">Sub1</a><a ui-sref="Sub2">Sub2</a>'
          },
          'content': {
            template: '<p>This is the content in Main1</p>'
          }
        }
      })
    

    工作状态

      .state('Main2', {
        url: '/Main2',
        views: {
          '': {
            templateUrl: 'layout.html'
          },
          'mainNav@Main2': {
            template: '<a ui-sref="Main1">Main1</a><br />'
                    + '<a ui-sref="Main2">Main2</a><br />'
                    + '<a ui-sref="Main3">Main3</a>'
          },
          'subNav@Main2': {
            template: '<a ui-sref="Sub1">Sub for Main2</a>'
          },
          'content@Main2': {
            template: '<p>This is the content in Main2</p>'
          }
        }
      })
      .state('Main3', {
        parent: 'index',  // PARENT does the trick
        url: '/Main3',
        views: {
          'subNav': { // PARENT contains the anchor/target - relative name is enough
            template: '<a ui-sref="Sub1">Sub for Main3</a>'
          },
          'content': {
            template: '<p>This is the content in Main3</p>'
          }
        }
      })
    

    【讨论】:

    • 感谢您的回答 Radim。我一直在试图弄清楚视图名称的语法(如detail@index)是如何工作的,但我还没有弄清楚。我现在正在组装一个 Plunkr,我会在这里链接它。
    • 这是我遇到的问题。请注意,每当您单击“Main1”时,一切都会消失。我尝试过以不同的方式使用@ 语法,但不知道如何让它工作。 plnkr.co/edit/TF7x5spB8zFLQPzrgZc9?p=preview
    • 感谢 Radim,现在更清楚了,在查看了您的其他示例后,我能够让 Main1 工作。每当您从一种状态切换到另一种状态时,有什么方法可以保持其中一个视图不变?所以每当我从Main2 切换到Main3 时,我是否可以保持内容页面不变,直到我点击子导航部分中的某些内容?
    • 是的,一切皆有可能,你去吧:plnkr.co/edit/Dz6ag35QZxxIj40xjy3m?p=preview。只有在选择子菜单时,才会在两个主轴(3,4)中定义内容。享受 ui-router
    • 非常感谢 Radim。这正是我所需要的。
    猜你喜欢
    • 2016-09-12
    • 2015-04-17
    • 1970-01-01
    • 2021-02-12
    • 2020-10-07
    • 2019-04-20
    • 1970-01-01
    • 1970-01-01
    • 2016-10-27
    相关资源
    最近更新 更多