SHOEISHA iD

※旧SEメンバーシップ会員の方は、同じ登録情報(メールアドレス&パスワード)でログインいただけます

DeveloperZine(デベロッパージン)- エンジニアの意思決定を支える技術情報メディア ProductZine

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

AngularJSではじめるJavaScriptフレームワーク開発スタイル

AngularJSのリリース前の新しいルーター機能(ngNewRouter)を触ってみよう

AngularJSで初めるJavaScriptフレームワーク開発スタイル 第10回

コンポーネントの作成

 先ほどパスとコンポーネント名だけを指定しましたが、これではあまりにも設定が少なすぎると思った方もいるのではないでしょうか。

 ngNewRouterではコントローラ名とテンプレートファイル名に命名規則があります。例えば、homeというコンポーネント名であれば、コントローラ名は「HomeController」という名称である必要があり、HTMLのテンプレートファイルは、components/home/home.htmlというファイル名である必要があります。

 コントローラを定義するファイル名は特に決まりはありませんが、今回は公式サンプルと同様にコントローラもcomponents/home/home.jsに配置します。このようなルールは好みもありますが、まずはデフォルトのルールでできるだけ利用するようにしましょう。

 続いてhomeコンポーネントを作成します。テンプレートファイルはリスト3のようになります。

リスト3 homeコンポーネントのHTMLテンプレート(router/components/home/home.htmlの抜粋)
<h1>Welcome HOME</h1>
<!-- (1) 他のコンポーネントへのリンク -->
<a ng-link="item({id: 342})">商品342へのリンク</a><br />
<!-- (2) データバインディングの利用 -->
<div>
    <input type="text" ng-model="home.item_id"><br />
    <a ng-link="item({id: home.item_id})">商品{{home.item_id}}へのリンク</a>
</div>

 (1)のng-link属性を使って他のコンポーネントへのリンクを定義します。直接URLを使って、例えば「#/item/342」のように指定したくもなりますが、現在そのような指定での遷移はできないようです。

 また、引数がない場合にはコンポーネント名だけで問題ありません。

 続いて、コントローラ側と変数をバインドするときの例ですが、必ず変数のプレフィックスとしてコンポーネント名がつきます。

 このあたりも好みが分かれる事でしょう。また、この影響はリスト4のようにコントローラを作成する際にもあります。

リスト4 homeコンポーネントのコントローラの実装(components/home/home.jsの抜粋)
(function(module){
    // (1) コントローラは別のモジュールでも同じモジュール内でも可能
    module.controller('HomeController',[HomeController]);

    function HomeController(){
        // (2) $scopeは使えない。 thisに設定した値が自動的にバインディング対象になる
        this.item_id = 123;
    }
}(this.module));

 まず、(1)ではHomeControllerを作成していますが、いつもの$scopeの指定はできません。

 $scopeを指定するとngNewRouterではコントローラの作成に失敗します。原因がエラーメッセージに表示されないので注意しましょう。

 このように、コンポーネント用のコントローラと今まで使っていたコントローラでは少々制限が違うようです。

 また、$scopeが使えない代わりに(2)のようにthisを使います。今までも、「<div ng-controller="HomeController as home">」のようにコントローラを指定できましたが、同じような感じになるのかと思います。

 続いて、パスからパラメータを取得する方法はリスト5のようになります。

リスト5 homeコンポーネントのコントローラの実装(router/components/home/home.jsの抜粋)
(function(){
    // (1) 別のモジュールとして作成することも可能
    var module = angular.module('app.item',['ngNewRouter']);

    // (2) URLハッシュ(/item/:id)からidパラメータを取得する
    module.controller('ItemController',['$routeParams',function($routeParams){
        this.id = $routeParams.id;
    }]);
}());

 homeコンポーネントはメインとなるモジュールに定義しましたが、(1)のように別のモジュールとして定義することももちろん可能です。その場合には、依存モジュールとして指定することを忘れないようにしてください。

 パスから指定のパラメータを取得するには、(2)のように$routeParamsオブジェクトのプロパティとして取得できます。

 また、どうしてもコンポーネントを作成する際のデフォルトのコントローラ名のルールや、テンプレートのファイルの命名規則を変えたい場合にはリスト6のように$componentLoaderProviderを利用して変更します。

 記述してあるルールはデフォルトのルール実装になっていますので、それらを参考にして自分の好みにあったルールに変えることは比較的容易に行えます。

リスト6 コントローラとテンプレートのデフォルトの命名規則の変更(router/app.jsの抜粋)
module.config(['$componentLoaderProvider', function ($componentLoaderProvider) {
    $componentLoaderProvider.setComponentFromCtrlMapping(function(name){
        //	新しいコントローラの命名規則を定義
        var ret = name[0].toLowerCase() + name.substr(1, name.length - "Controller".length - 1);
        return ret;
    });

    $componentLoaderProvider.setTemplateMapping(function(name){
        //	新しいテンプレートファイルの命名規則を定義
        var dashName = dashCase(name);
        var ret =  './components/' + dashName + '/' + dashName + '.html';
        return ret;
    });
}]);

複数のビューを表示する

 これまでは1つのパスにつき1つのビューでしたが、ngNewRouterでは複数のビューとコンポーネントをセットにして、パスと連動して定義することができることが特徴的です。

 ポータレット、もしくはウィジェットの集合であるダッシュボードのような画面が作りやすくなっていると感じました。

 そのためか、実はng-viewportという命名は、現在の開発レベルではng-outletに変わろうとしていますのでngNewRouterではこの機能の特徴が名前にも現れているのではないかと思っています。

 ただし、サンプルでは簡略化の為に図2のように共通するヘッダと異なる画面の表示にて説明します。

 複数のビューの指定は、リスト7のようにng-viewportに必ず値を指定し名称を設定します。先ほどの例で名称を指定していませんでしたが、その場合にはdefaultとい名称を指定したことと同じになります。

図2 複数のビューを表示したときの実行結果例
図2 複数のビューを表示したときの実行結果例
リスト7 homeコンポーネントのコントローラの実装(router2/app.jsの抜粋)
<body ng-app="app">
    <div ng-viewport="header"></div>
    <div ng-viewport="main"></div>
</body>

 続いて、コンポーネントの指定では先ほど指定した名称を利用し、リスト8のように指定します。

リスト8 複数のコンポーネントの指定(router2/app.jsの抜粋)
AppController.$routeConfig = [
    {path: '/',           redirectTo: '/home'},
    {path: '/home'  ,     components: { header : 'header' , main : 'home' }, as : 'home'},
    {path: '/info' ,      components: { header : 'header',  main : 'info' }, as : 'info'}
];

 headerには共通の「header」コンポーネントを指定していますが、mainには別のコンポーネントを指定して表示を切り分ける事ができます。

 また、複数のコンポーネントを指定している場合には、asを使ってng-linkで利用するリファレンス名を指定します。

 コンポーネントの作成方法はこれまでと同様です。

次のページ
最後に

この記事は参考になりましたか?

AngularJSではじめるJavaScriptフレームワーク開発スタイル連載記事一覧

もっと読む

この記事の著者

山田 祥寛(ヤマダ ヨシヒロ)

静岡県榛原町生まれ。一橋大学経済学部卒業後、NECにてシステム企画業務に携わるが、2003年4月に念願かなってフリーライターに転身。Microsoft MVP for Visual Studio and Development Technologies。執筆コミュニティ「WINGSプロジェクト」代表。主な著書に「独習シリーズ(Java・C#・Python・PHP・Ruby・JSP&サーブレットなど)」「速習シリーズ(ASP.NET Core・Vue.js・React・TypeScript・ECMAScript、Laravelなど)」「改訂3版JavaScript本格入門」「これからはじめるLaravel実践入門」「はじめてのAndroidアプリ開発 Kotlin編 」他、著書多数

※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です

WINGSプロジェクト 小林 昌弘(コバヤシ マサヒロ)

WINGSプロジェクト について> 有限会社 WINGSプロジェクト が運営する、テクニカル執筆コミュニティ(代表 ...

※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です

この記事は参考になりましたか?

この記事をシェア

CodeZine(コードジン)
https://codezine.jp/article/detail/8744 2015/06/23 14:00

イベント

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

新規会員登録無料のご案内

  • ・全ての過去記事が閲覧できます
  • ・会員限定メルマガを受信できます

メールバックナンバー