2014-02-28 27 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