【AngularJS】angular-ui-routerを使ってメニューから表示する内容を切り替える
10cmです。こんにちは。今回は、AngularJSの"angular-ui-router"(以下、ui-router)を用いて、メニューバーから表示する内容を切り替える処理を記載していきます。
はじめに、完成イメージです。 "コンテンツA"と"コンテンツB"のリンクがあり、それぞれ専用の画面を表示します。今回の例では、"コンテンツA"は赤い四角を、"コンテンツB"は緑の四角を表示します。
コンテンツA
コンテンツB
以下に、今回のディレクトリ構成を示します。
ディレクトリ構成 ---------------------- カレントディレクトリ ├ index.html ├ app.js ├ controller │ └ header.js ├ view │ ├ main.html │ ├ header.html │ ├ contentA.html │ └ contentB.html └ node_modules ├ angular └ angular-ui-router
- メニューの作成 (header.html, header.js)
- コンテンツの作成 (contentA.html, contentB.html)
- メニューとコンテンツの紐付け (index.html, main.html, app.js)
- まとめ
- 参考
メニューの作成 (header.html, header.js)
まず、メニューの作成を行います。以下にソースコードを示します。header.html ---------------------- <header> <ul ng-repeat="l in HeaderCtrl.list"> <a ui-sref="main.{{l.link}}"><li>{{l.name}}</li></a> </ul> </header>
header.js ---------------------- var HeaderCtrl = function($scope) { this.list = [ { 'link': 'contentA', 'name': 'コンテンツA' }, { 'link': 'contentB', 'name': 'コンテンツB' } ]; }; app.controller('HeaderController', HeaderCtrl);
"a"タグの中に書かれている"ui-sref"ですが、詳しくは後ろで解説します。ここでは"href"のように、飛ぶ先を示しているのだと認識してください。つまり、『"main.{{l.link}}という場所が設定されていて、リンクを押すとそこに飛ぶんだな。』ということです。
l.linkは、"header.js"に書いてある"list"の中身を、1つずつ取り出しています。この例では、"コンテンツA"と画面上に表示されていて、そのリンク先は"main.contentA"となります。
コンテンツの作成 (contentA.html, contentB.html)
次に、メニューを押下した時に表示するコンテンツを作成します。といっても、ここでは四角を表示するHTMLファイルを書くだけです。一応ソースコードは以下のようになります。
contentA.html ---------------------- <div style="height:100px; width:100px; background-color:#ff0000"> <p style="color: #ffffff">ContentA</p> </div>
contentB.html ---------------------- <div style="height:100px; width:100px; background-color:#00ff00"> <p style="color: #000000">ContentB</p> </div>
メニューとコンテンツの紐付け (index.html, main.html, app.js)
ここでメニューと作ったコンテンツの紐付けを行います。その前に、表示切り替えのイメージの説明をしたいと思います。メニューが選択されたとき、設定されていた"ui-sref"の値を表示しろと"app.js"に通知します。"app.js"は、その値に紐づくHTMLファイルを"main.html"に表示させます。
そのため、メニューに設定している"ui-sref"の値と、"app.js"に記載する値を一致させる必要があります。それでは、実際のソースコードを見てみましょう。
index.html ---------------------- <body ng-app="MyApp"> <!-- UI-Routerの設定 --> <ui-view name="header"></ui-view> <ui-view name="main"></ui-view> </body>
main.html ---------------------- <ui-view name="content"></ui-view>
app.js ---------------------- var app = angular.module('MyApp', ['ui.router']); app.config(function($stateProvider, $urlRouterProvider){ $stateProvider.state('main',{ 'url': '/', 'views': { // Header 'header': { 'templateUrl': './view/header.html', 'controller': 'HeaderController', 'controllerAs': 'HeaderCtrl' }, 'main': { 'templateUrl': './view/main.html', } //ContentA }}).state('main.contentA', { 'url': 'contentA', 'views': { 'content': { 'templateUrl': './view/contentA.html', } //ContentB }}).state('main.contentB', { 'url': 'contentB', 'views': { 'content': { 'templateUrl': './view/contentB.html', } }}); $urlRouterProvider.otherwise('/'); });
"index.html"には、メニューと、 コンテンツを表示するための"ui-view"があります。メニューには"header.html"を、コンテンツには"main.html"をapp.jsで指定しています。
"main.html"には、"content"を表示するための"ui-view"が設定されています。ここに対して、"contentA"か"contentB"のHTMLファイルを表示します。
では、どうやって表示するものを決定するかですが、"app.js"の"state"に書かれています。"contentA"の場合は"main.contentA"が設定されています。これは、"header.html"のui-sref"と同じ値が設定されています。
つまり、コンテンツAを押下したとき、"ui-sref"に設定されている"state"と同じものを表示させます。では何を表示させるのか。"content"の"templateUrl"に設定されているHTMLを表示させます。今回の例では、"./view/contentA.html"が表示されます。
まとめ
"ui-view"を階層化することで、表示するものを切り替えることができるようになりました。"ui-view"や"ui-sref"、"app.js"に記述する"state"など色々出てきましたが、それぞれの関連性について理解できたでしょうか?ここで言うのもなんですが、自分はまだ理解できていないと思います(汗)。