吉本集の個人ブログ
Web制作の技術について書いています。たまに日記も書きます。

HTMLを細分化して読み込む

2013年11月26日 / category : angularjs, lab, その他

メインのHTMLに、別のHTMLを読み込んでみます。
別のHTMLを読み込むときには、いくつか用意が必要です。

1.メインのHTML側に、ng-view属性を設定する(これが読み込まれる箱になります)
2.別モジュールの「angular-route.min.js」が必要
3.外部HTMLに対し、URLとcontroller属性がそれぞれ必要となる

以上の3点が必要です。

【1.メインのHTML側に、ng-view属性を設定する】

<div ng-view></div>

ng-view属性を設定することで、外部HTMLを読み込む場所を指定できます。

【2.別モジュールの「angular-route.min.js」が必要】
AngularJS公式サイトからダウンロードしたファイル一式の中に、「angular-route.min.js」が格納されていますので、
まずjsファイルを読み込みます。

<script src="js/libs/angular-route.min.js"></script>

このモジュールを読み込むには、

var myApp = angular.module('app', ['ngRoute']);

と指定します。(モジュール名がngRouteです。)

【3.外部HTMLに対し、URLとcontroller属性がそれぞれ必要となる】
モジュールの読み込みが完了した後、URLに対し、どの外部HTMLを読み込むかを指定します。
指定形式は下記となります。

myApp.config(['$routeProvider',
	function($routeProvider){
		$routeProvider.when('URL-A', オブジェクト-A);
		$routeProvider.when('URL-B', オブジェクト-B);
		$routeProvider.otherwise({redirectTo: 'リダイレクト先のURL'});
	}
]);

引数$routeProviderの中に、ngRouteモジュールが格納されます。($routeProviderは固定値です。)
config関数の中で、ngRouteモジュールが持つwhen関数を設定し、URLと外部HTMLの参照先を含むオブジェクトを指定します。
それでは、外部HTMLの参照先を含むオブジェクトを詳しく見ていきます。

myApp.config(['$routeProvider',
    function($routeProvider){
        $routeProvider.when('URL-A', {
        	templateUrl: 'HTMLの参照先-A',
        	controller: コントローラー名(コンストラクタ関数名)-A
        })
        .when('URL-B', {
        	templateUrl: 'HTMLの参照先-B',
        	controller: コントローラー名(コンストラクタ関数名)-B
        })
        .otherwise({
        	redirectTo: 'リダイレクト先のURL'
        });
    }
]);

templateUrlには、変更されるURLを指定します。
controllerは、グローバル関数名(コントローラー名)となります。
このオブジェクトには他にも指定できる値がありますが、今回のサンプルでは、この2つのみを設定します。

それではサンプルを見ていきます。

■サンプルURL
http://tsudoi.org/javascript/angularjs/Reference/Blog/3/
■サンプルファイル一式
ダウンロード – zip
■HTML – index.html
<!doctype html>
<html ng-app="app">
<head>
<meta charset="utf-8">
<title></title>
<script src="js/libs/jquery-2.0.3.min.js"></script>
<script src="js/libs/angular.min.js"></script>
<script src="js/libs/angular-route.min.js"></script>
<script src="js/app.js"></script>
<script src="js/controllers.js"></script>
<link href="css/reset.css" rel="stylesheet">
<link href="css/styles.css" rel="stylesheet">
</head>
<body>

<div id="container" ng-controller="MainCtrl">

<p>ページ切り替え : <a href="#/photo0/">赤いかぼちゃ</a> | <a href="#/photo1/">黄色いかぼちゃ</a></p>
<div id="viewBox">
<div ng-view></div>
</div>
<p>root msg : {{msg}}</p>

</div>

</body>
</html>
■HTML – templateA.html
<p><img src="images/photo0.jpg" width="640" height="427" alt=""></p>
<p>view msg : {{msg}}</p>
■HTML – templateB.html
<p><img src="images/photo1.jpg" width="640" height="427" alt=""></p>
<p>view msg : {{msg}}</p>
■JavaScript – app.js
var myApp = angular.module('app', ['ngRoute']);

myApp.config(['$routeProvider',
	function($routeProvider){
		$routeProvider.when('/photo0/', {
			templateUrl: 'templateA.html',
			controller: CtrlA
		});
		$routeProvider.when('/photo1/', {
			templateUrl: 'templateB.html',
			controller: CtrlB
		});
		$routeProvider.otherwise({
			redirectTo: '/photo0/'
		});
	}
]);
■JavaScript – controllers.js
//index.htmlのng-controller="MainCtrl"範囲内のコンストラクタ関数
myApp.controller('MainCtrl', ['$scope', function($scope){
	$scope.msg = 'html = index.html, ng-controller = MainCtrl';
}]);

//templateA.htmlのコンストラクタ関数
function CtrlA($scope){
	$scope.msg = 'html = templateA.html, ng-controller = CtrlA';
}

//templateB.htmlのコンストラクタ関数
function CtrlB($scope){
	$scope.msg = 'html = templateB.html, ng-controller = CtrlB';
}
■解説
ngRouteモジュールのwhen関数で、コンストラクタ関数を指定する方法が2種類有ります。
今回はcontrollerを指定しました。controllerを指定した場合は、コンストラクタ関数はグローバル関数での設定となります。
$routeProvider.when('/photo0/', {
    templateUrl: 'templateA.html',
    controller: CtrlA
});

↑この指定の場合は、

function CtrlA($scope){}

↑この指定方法(グローバル関数)となります。

myApp.controller('CtrlA', ['$scope', function($scope){}]);//エラー

↑この指定方法(コントロール関数)ではエラーになります。

コンストラクタ関数をコントロール関数で設定する場合は、controllerAsを使用するのですが、この解説は次回とします。
また、今回のサンプルで、もうひとつ注意しなければいけないのが、index.htmlで下記のスクリプトを読み込んでいることです。
<script src="js/libs/jquery-2.0.3.min.js"></script>
この読み込みを外して閲覧し、外部HTMLの切り替えをすると、Google Chromeのブラウザで下記のようなエラーが出ます。
event.returnValue is deprecated. Please use the standard event.preventDefault() instead.
angular.min.js:26
このエラーは、おそらく、angular.min.jsの中で読み込んでいるjqueryのバージョンが対応できていないからだと思います。
最新のjqueryを読み込むことで、このバグは回避できます。