2014-02-28 25 views
37

给定一个HTML文件,像这样:Angular UI-Router如何创建一个“布局”状态?

<html> 
<header ui-view="header"></header> 
<div class="main" ui-view></div> 
<footer ui-view="footer"></footer> 
</html> 

如何将一个创建,填补了“头”有头模板,与页脚模板页脚的布局状态,然后让孩子的状态,以填补空UI的看法?

我想空的ui-view也可以命名为ui-view =“main”。

回答

31

一种方法是创建一个全局“根”状态。所以,每个状态将是它的孩子。 像root.pages,root.pages.edit,root.settings等 然后,您可以为页眉和页脚提供默认模板。

我个人使用的另一种方法,不同的方法是使用ng-include作为页眉和页脚。

<body ng-controller="AppCtrl"> 
    <div id="header" ng-include="'header.tpl.html'"></div> 
    <div class="main_container" ui-view> 
    </div> 
</body> 

Btw。我在header.tpl.html使用单独的控制器,也就是主AppCtrl:一个孩子

<div id="header" ng-controller="HeaderCtrl"> .... 
+2

这是一个非常好的主意。 “layout”或“root”状态有用的原因是,在应用程序内部时,“标题”或“页脚”可能会更改。如内部帐户管理与外部演示网站之间。虽然在这个根状态下,它是一个抽象的状态,我猜它没有url属性吗? (我也喜欢AppCtrl,我一直在使用app.run(function(){})作为根控制器 – CMCDragonkai

+0

是的,根状态可能是一个抽象状态 虽然,抽象状态应该有它的URL。可以用来为子状态预先设置一个url,但是对于根状态,它可以保持为'/'。 这里是关于ui-router中抽象状态的详细信息:https://github.com/angular-ui/ ui-router/wiki/Nested-States-%26-Nested-Views#维基抽象状态 至于控制器,你可以让你的主应用程序控制器作为该根状态的控制器,它将工作 –

+0

我会有一个家庭状态URL是'/'。所以我不认为我的抽象状态可以在这种情况下有一个网址。 – CMCDragonkai

77

试试这个,实际上您的页眉和页脚是静态的模板,但你可以添加的情况下,你需要添加控制器给它一些动态的功能,页眉和页脚将被默认,因为路径是“”,所以尝试了这一点包括:

app.config(['$stateProvider', function($stateProvider){ 
     $stateProvider 
     .state('root',{ 
      url: '', 
      abstract: true, 
      views: { 
      'header': { 
       templateUrl: 'header.html', 
       controller: 'HeaderCtrl' 
      }, 
      'footer':{ 
       templateUrl: 'footer.html', 
       controller: 'FooterCtrl' 
      } 
      } 
     }) 
     .state('root.home', { 
      url: '/', 
      views: { 
      '[email protected]': { 
       templateUrl: 'homePage.html' 
      } 
      } 
     }) 
     .state('root.other', { 
      url: '/other', 
      views: { 
      '[email protected]': { 
       templateUrl: 'other.html' 
      } 
      } 
     });  

    }]); 

编辑: 给我设置的意见,最好的地方应该在index.html 和类似的代码:

<header> 
    <div ui-view="header"></div> 
</header> 
<div ui-view="container"> 
</div> 
<footer id="mainFooter" ui-view="footer"> 
</footer> 
+0

我似乎无法获取homePage.html呈现。它抓取HTML但不注入UI视图。我没有收到任何错误。思考? –

+0

查看ui-router文档中的命名视图:https://github.com/angular-ui/ui-router/wiki/Multiple-Named-Views –

+0

谢谢!帮助如此之多。容器@必须在html的空白ui-view上,现在可以运行了 –

5

根据Jack.the.ripper的回答,我创建了这个解决方案。

卡斯:我有一个微小的变化,我真的想要2布局。一个公众和一个私人。 在Meteor with Blaze和Iron Router中,有一个很好的解决方案,您可以定义哪个主模板将用于特定路线。 这个我现在已经能够设置谢谢杰克!

注:代码将在翡翠和咖啡,它是一个Meteor + Angular项目。 使用http://js2.coffee/转换为Javascript。

# the ROUTER part 
# 
angular.module('myApp').config(

    ($urlRouterProvider, $stateProvider, $locationProvider) -> 
    $locationProvider.html5Mode true 

    $stateProvider 
     .state('private', 
     url: '' 
     abstract: true 
     views: 
      'app': 
      templateUrl: 'client/views/layouts/privateLayout.html' 
    ) 

     .state('public', 
     url: '' 
     abstract: true 
     views: 
      'app': 
      templateUrl: 'client/views/layouts/publicLayout.html' 
    ) 

     .state('private.home', 
     url: '/' 
     views: 
      "[email protected]": 
      templateUrl: 'client/views/home/home.html' 
    ) 

     .state('public.login', 
     url: '/login' 
     views: 
      "[email protected]": 
      templateUrl: 'client/views/session/login.html' 
    ) 
     $urlRouterProvider.otherwise '/' 
) 

这是定义应用视图的索引文件,它将利用路由器中定义的抽象状态。

head 
meta(name="viewport" content="width=device-width, initial-scale=1") 
base(href="/") 

body(layout="column") 
    div(ui-view="app" layout="column" flex) 

然后私人布局与其容器视图。

div(layout="column" flex) 
    div(ng-controller="AppCtrl" layout="row" flex) 

    //- some private Layout stuff happening here.... 
    md-content(flex layout-padding) 
    div(ui-view="container" layout="column") 

终于公共布局及其容器视图

div.public-layout(layout="column" flex) 
    div(ui-view="container" layout="column" flex) 

有了这个设置,我可以设置登录页面通过这条路线的观点,说明使用抽象公众的布局,它应该使用从公共视图中查看container @ public,使用视图Container。在这个视图中加载login.html。

同样的主页,这个加载容器@私人意味着私人视图的容器视图。

这似乎工作就像一个魅力。

非常感谢杰克,也是Angular UI Router - Nested States with multiple layouts的答案的作者,这帮助我找到了最终的解决方案。

干杯

21

实际上有一个非常简单的方法来做到这一点。

1.创建

$stateProvider 
    .state('master', { 
    abstract: true, 
    views: { 
     layout: { 
     templateUrl: '/layouts/master.html', 
     } 
    } 
    }); 

2.使用未命名视图状态的布局内的布局状态

<!-- layouts/master.html --> 
<div ui-view></div> 

3.创建视图状态

$stateProvider 
    .state('home', { 
    url: '/', 
    templateUrl: '/views/home.html', 
    parent: 'master', 
    }); 

4.使用命名布局状态为根状态

<!-- home.html --> 
<body ui-view="layout"></body> 
+1

在一个轻微的我倾向于这种方法,以便能够在移动和桌面应用程序之间共享控制器代码,并且可以为桌面或移动模板提供服务,以防有人想知道类似的事情会在此评论中绊倒。 – Fissio

+0

@Fissio您应该尝试共享代码槽服务,而不是通过控制器。但我认为这对模板助手很好,等等。 –

+1

是的,这就是我的意思。因为95%的控制器功能是共享的,所以移动设备和桌面设备使用不同的模板,但使用相同的控制器 – Fissio

1

类似jack.the.ripper的方式,你也能做到这一点它为我工作的方式。

app.config(function($stateProvider, $urlRouterProvider) { 
    $stateProvider 
    .state('root', { 
     /* The Root State */ 
     views: { 
     '': { 
      abstract: true, 
      templateUrl: 'master.html', 
      controller: 'mainController' 
     }, 
     '[email protected]': { 
      templateUrl: 'header.html', 
      controller: 'headerController', 
     }, 
     '[email protected]': { 
      templateUrl: 'footer.html', 
      controller: 'footerController' 
     }, 
    }, 
    }) 
    .state('root.index', { 
     /* The Index State */ 
     url: '/', 
     views: { 
     'content': { 
      templateUrl: 'index.html', 
      controller: 'indexController' 
     } 
     }, 
    .state('root.other', { 
     /* The Other State */ 
     url: '/', 
     views: { 
     'content': { 
      templateUrl: 'other.html', 
      controller: 'otherController' 
     } 
     }, 
    }); 
}); 

在我们index.html我们只会有一个<ui-view></ui-view>

master.html看起来像

<div ui-view="header"></div> 
<div ui-view="content"></div> 
<div ui-view="footer"></div> 

为什么我选择了这种方法,是我没有创建一个单独的全局控制器,而我的mainController将成为全球控制器。

0

而不是使用路径在所有的头和页脚,我会使用Angular组件,现在它们可用1.5倍。

它的方式更加灵活,您不必处理root.whatever或ngInclude。我进入它在这里更详细:https://stackoverflow.com/a/41093339/2416007,但本质上你:

1.创建组件

(function() { 
'use strict'; 
angular 
    .module('layout') 
    .component('layoutHeader', { 
     templateUrl: 'layout/header.html', 
     bindings: {}, 
     controller: Controller 
    }); 

Controller.$inject = []; 
function Controller() { 
    var ctrl = this; 

    initialize(); 

    //////////////////// 

    function initialize(){ 

    } 

} 
}()); 

2.将它添加到您的类似index.html页面或

<layout-header></layout-header> 

3.相同的页脚

<layout-footer></layout-footer> 

4。在身体的结果是

<layout-header></layout-header> 
<main ui-view></main> 
<layout-footer></layout-footer> 
+0

组件与使用ui-router不同。 ui-router将允许你根据url选择模板/控制器配置。如上所述使用命名视图将允许基于$ state交换模板 – Kieran