从ui-router中的较低状态覆盖较高状态的布局视图会导致空ui-view

Tre*_*nes 8 javascript state angularjs angular-ui-router

我正在尝试使用ui-router在角度中使用嵌套状态创建一个基本布局系统.

我想要的是,任何"子状态"都可以覆盖'layout'顶级状态的部分,以便根据站点的区域使用不同的站点布局.

给定以下system/server/views/index.html:

<section data-ui-view="layout" ></section>
Run Code Online (Sandbox Code Playgroud)

以及两个可以互换的布局:system/public/views/layouts/standard.html:

  <div class="navbar navbar-inverse navbar-fixed-top" data-ui-view="header" data-role="navigation"></div>
  <section class="container-fluid">
      <section data-ui-view ></section>
  </section>
Run Code Online (Sandbox Code Playgroud)

系统/公/视图/布局/全width.html:

  <div class="navbar navbar-inverse navbar-fixed-top" data-ui-view="header" data-role="navigation"></div>
  <section class="container">
      <section data-ui-view ></section>
  </section>
Run Code Online (Sandbox Code Playgroud)

样本内容系统/ public/views/index.html

<div>some sample content</div>
Run Code Online (Sandbox Code Playgroud)

最后是路由器:

function($stateProvider, $urlRouterProvider) {
  // For unmatched routes:
  $urlRouterProvider.otherwise('/');

  // states for my app
  $stateProvider
    .state('root', {
      url: '/',
      abstract: true,
      views: {
        'layout@': {
          templateUrl: 'system/views/layouts/standard.html'
        },
        'header@root': {
          templateUrl: 'system/views/partials/header.html'
        }
      }
    })
    .state('root.home', {
      url: '',
      views: {
        'header@root': {
          templateUrl: 'system/views/partials/header2.html'
        },
        '': {
          templateUrl: 'system/views/index.html'
        }
      }
    });
}
Run Code Online (Sandbox Code Playgroud)

以上工作.我可以在子状态中交换标头,但是如果我为'布局'添加覆盖:

function($stateProvider, $urlRouterProvider) {
  // For unmatched routes:
  $urlRouterProvider.otherwise('/');

  // states for my app
  $stateProvider
    .state('root', {
      url: '/',
      abstract: true,
      views: {
        'layout@': {
          templateUrl: 'system/views/layouts/standard.html'
        },
        'header@root': {
          templateUrl: 'system/views/partials/header.html'
        }
      }
    })
    .state('root.home', {
      url: '',
      views: {
        'header@root': {
          templateUrl: 'system/views/partials/header2.html'
        },
        '': {
          templateUrl: 'system/views/index.html'
        },
--->>> 'layout@': {
          templateUrl: 'system/views/layouts/full-width.html'
        }
      }
    });
}
Run Code Online (Sandbox Code Playgroud)

当我加入'layout@'date-ui-view="layout"不被正确加载,但页眉和unamed子UI的意见没有得到更换.

有什么想法在这里发生了什么?

如果这不是可行的东西,那么替代方法是什么?

Rad*_*ler 15

重点是在子状态中覆盖模板,'root.home'如下所示:

.state('root.home', {
    ...
->> 'layout@': {
      templateUrl: 'system/views/layouts/full-width.html'
    }
Run Code Online (Sandbox Code Playgroud)

事实上,完全从父"root"中删除任何部分.所以现在我们必须将它用于兄弟视图:

    'header@root.home': {  // see the 'root.home' after @
      templateUrl: 'system/views/partials/header2.html'
    },
    '@root.home': {        // see the 'root.home' after @
      templateUrl: 'system/views/index.html'
    },
Run Code Online (Sandbox Code Playgroud)

看,我们用过root.home之后@.那就是:我们明确地说:

  • 找到这个当前状态的ui-view="header"未命名ui-view=""内容.'root.home'

父状态'home'中没有目标存在,因为我们完全跳过它.

在这种情况下,文档中的示例实际上是自描述的:

查看名称 - 相对名称与绝对名称

(引用自描述片段)

$stateProvider
  .state('contacts', {
    // This will get automatically plugged into the unnamed ui-view 
    // of the parent state template. Since this is a top level state, 
    // its parent state template is index.html.
    templateUrl: 'contacts.html'   
  })
  .state('contacts.detail', {
    views: {
        ////////////////////////////////////
        // Relative Targeting             //
        // Targets parent state ui-view's //
        ////////////////////////////////////

        // Relatively targets the 'detail' view in this state's parent state, 'contacts'.
        // <div ui-view='detail'/> within contacts.html
        "detail" : { },            

        // Relatively targets the unnamed view in this state's parent state, 'contacts'.
        // <div ui-view/> within contacts.html
        "" : { }, 

        ///////////////////////////////////////////////////////
        // Absolute Targeting using '@'                      //
        // Targets any view within this state or an ancestor //
        ///////////////////////////////////////////////////////

        // Absolutely targets the 'info' view in this state, 'contacts.detail'.
        // <div ui-view='info'/> within contacts.detail.html
        "info@contacts.detail" : { }

        // Absolutely targets the 'detail' view in the 'contacts' state.
        // <div ui-view='detail'/> within contacts.html
        "detail@contacts" : { }

        // Absolutely targets the unnamed view in parent 'contacts' state.
        // <div ui-view/> within contacts.html
        "@contacts" : { }

        // absolutely targets the 'status' view in root unnamed state.
        // <div ui-view='status'/> within index.html
        "status@" : { }

        // absolutely targets the unnamed view in root unnamed state.
        // <div ui-view/> within index.html
        "@" : { } 
  });
Run Code Online (Sandbox Code Playgroud)

另外,请注意这个重要的事实:

仅按视图层次结构的范围继承

请记住,只有嵌套状态的视图时,范围属性才会继承状态链.范围属性的继承与状态的嵌套以及与视图(模板)的嵌套有关的所有内容都无关.

完全有可能您有嵌套状态,其模板在您站点内的各种非嵌套位置填充ui-views.在这种情况下,您不能指望在子状态视图中访问父状态视图的范围变量.

也就是说 - 我们无法继承父"root"状态,因为继承只会查看视图...