AngularJSでは$routeとng-viewディレクティブが結びついていて、ルートに応じて指定したtemplateがng-view内にincludeされる仕組みになっています。しかし、ng-viewを複数置いてそれぞれに別のテンプレートを表示させる、といった複雑な事はできません。ある表示領域の下に別の表示領域を置きたい...事は頻繁にあるので結構困る。
こういった事は、ルーティングフレームワークui-routerを使うと簡単に実現できます
https://github.com/angular-ui/ui-router
ui-routerを使うと、各々の状態(state)に「名前をつける」「入れ子にする」「並列に表示させる」
事ができ、インターフェースを格段に柔軟に扱うことができます。開発も非常に活発。
ありがちなwebサービスの画面を例として、ネストされたビューの構築手順を紹介します
青い領域が親(=設定を押したら変化する領域)、ピンクの領域が子(=プロフ編集etcを押したら変化する領域)です
サイドバーのリンクをクリックすると、ピンクの領域のみリフレッシュされる状態を目指します。
ビューの配置
setupまでは終わっているものとします
レイアウトファイルに、青い領域を表示させるビューを配置します
ui-routerではビューの表示にはui-viewを使うことに注意(not ng-view)
<body>
<h1>This is top level view of app</h1>
<div class="contents">
<div ui-view></div> <!-- blue -->
</div>
</body>
このui-viewの中にincludeされる設定画面は以下です。この中に更にui-viewがあり入れ子にさせています。この中に各種設定用のhtmlが読み込まれる形です。
<!-- settings -->
<div class="side-bar">
<a ui-sref="settings.profile">プロフ編集</s>
<a ui-sref="settings.mail">メール設定</s>
<a ui-sref="settings.background">背景設定</s>
<a ui-sref="settings.password">パスワード変更</s>
<div ui-view></div> <!-- pink -->
<div>
<h1>profile settings</h1>
<!-- hogehoge -->
ui-srefディレクティブは、stateProviderでルーティングした状態名を指定すると、よしなに対応するリンク先を設定してくれます。ルーティング処理を見てみましょう。
myApp.config (function($stateProvider, $urlRouterProvider) {
$stateProvider
.state('settings', {
url: '/settings',
controller: 'SettingsCtrl',
templateUrl: 'settings.html'
})
.state('settings.profile', {
url: '/account',
controller: 'SettingsCtrl',
templateUrl: 'settings/profile.html'
})
});
stateの第一引数が状態名で、ui-srefで指定するものと同一にします
ポイントは、入れ子にする時はドットで区切ることです。
settings.profileだとsettingが親で、profileが子になります。
親子関係が構築され、settings.profile内の設定は親の状況を引き継ぎます。
urlは/settings/accountになり、templateUrlのsettings/profile.htmlの挿入先は親の
templateUrl内(=settings.html)のui-viewになります。
これで、サイドバーのリンクをクリックしても、ピンクの領域のみリフレッシュされるようになります
こちらは簡単な例ですが、他にも便利な機能が沢山あるので是非試してみてください