●サンプル
HogeControllerのボタンをクリックすると、requirejsでコントローラー、テンプレートを
ロードし、テンプレートの内容をtestWidgetに追加する。
追加した内容は、ロードしたコントローラーに紐づいてるので、
ボタンを押すと、ロードしたコントローラーのイベントが起動する。
[画面html]
index.html
<!DOCTYPE html>
<html lang="ja" >
<head>
<meta charset="utf-8">
<title>angular require test 1</title>
<!-- requiejsのエントリ -->
<script data-main="dist/js/app/boot.js?hoge" src="dist/js/lib/require.js"></script>
</head>
<body>
<div ng-controller="HogeController as HogeC">
<button type="button" ng-click="HogeC.doClick()" >click</button>
</div>
<div>hello</div>
<div>
<testWidget>
<!-- 上のボタンを押すとコントローラーをロードして、ここにテンプレートの内容を挿入する -->
</testWidget>
</div>
</body>
</html>
[ボタンクリックでtestWidget挿入する内容のテンプレート]
test_template.html
<testWidgetSub ng-controller='FugaController'>
<div >{{'tttt'}}<button type='button' ng-click='doFuga()'>Fuga!</button></div>
</testWidgetSub>
[初期ロードjs]
boot.js
require.config({
paths: {
'angular': 'lib/angularjs/angular'
,'jquery': 'lib/jquery/jquery-2.1.0'
,'app': 'app/app'
,'hoge_controller': 'app/hoge_controller_define'
,'fuga_controller': 'app/fuga_controller_define'
}
,shim: {
"angular": {"deps": ["jquery"] ,"exports": "angular"}
,"app": {"deps": ["angular"]}
,"hoge_controller": {"deps": ["app"]}
,"fuga_controller": {"deps": ["app"]}
}
,baseUrl: 'dist/js'
// cache防止
,urlArgs: 'bust=' + (new Date()).getTime()
});
require([
'jquery' ,'angular' ,'app' ,'hoge_controller'
], function(jQuery ,angular ,app) {
console.log('boot app start.');
// DOMロード時、実行
$(function() {
angular.bootstrap(document, ['app']);
console.log("boot app end.");
});
});
[angularアプリ設定js]
app.js
define([
'angular' ,
'jquery'
], function (angular ,jQuery) {
// angularアプリケーションの初期化
var app = angular.module('app' ,[]);
// bootstrap後にcontrollerを追加出来るよう、controllerProvider設定
app.config(function($controllerProvider, $compileProvider, $filterProvider, $provide)
{
app.controllerProvider = $controllerProvider;
app.compileProvider = $compileProvider;
app.filterProvider = $filterProvider;
app.provide = $provide;
});
return app;
});
[angularコントローラーjs]
hoge_controller_define.js
define([
'angular',
'jquery',
'app'
], function (angular ,jQuery ,app) {
// HogeController定義
// このコントローラーは、angular.bootstrapまでに読み込まれる。
// なので、コントローラーの定義は、controller()で行う。
app.controller('HogeController' ,[
'$scope', '$compile', '$http',
function($scope ,$compile ,$http) {
this.doClick = function() {
console.log('click');
// testWidgetに追加されてない場合、ロードして追加。
var elm = angular.element('testWidget testWidgetSub');
if (elm.size() == 0) {
// FugaControllerを動的にロード
require([
'jquery' ,'angular' ,'app' ,'fuga_controller'
], function(jQuery ,angular ,app) {
// テンプレートを動的にロード
$http.get('dist/template/test_template.html')
.success(
function(data,status,headers,config) {
// ロードしたテンプレートをコンパイルして
// testWidgetに追加
var hogeViewTmpl = $compile(data)($scope);
app.directive('testWidgetSub' ,
function(scope) {
scope.$apply();
});
angular.element('testWidget').append(hogeViewTmpl);
})
.error(
function(data,status,headers,config) {
console.log('load template failed .');
}
);
});
}
}
}
]);
// angular.bootstrap()してないので、
// angular.controller('HogeController')は返せない...
return app;
});
[angularコントローラーjs(bootstrap後)]
fuga_controller_define.js
define([
'angular',
'jquery',
'app'
], function (angular ,jQuery ,app) {
// FugaController定義
// このコントローラーは、HogeController.doClickのイベントで読み込まれる。
// なので、コントローラーの定義は、controllerProvider.register()で行う。
app.controllerProvider.register('FugaController', [
'$scope', '$compile', '$http',
function($scope ,$compile ,$http) {
$scope.doFuga = function() {
console.log('fuga controller clicked!!!');
};
}
]);
return app.controller('FugaController');
});
●雑感
結構メンドクサイ処理になった。
最初から全部読み込んどく事、前提なのかな?
沢山画面あって階層型にする時でも、SPAでは、全部、読み込んどくベキなんだろうか?
●[TODO]
サービスについて調べてないけど、やっぱりプロバイダが必要?
require.configのpathsを後で追加出来るか調べる
(出来ない、もしくは、とてもメンドクサイ処理になりそう
→※require時、パスを指定して拡張子を付ければ読み込むが、イマイチ...)
$http.getをangularモジュールの外部から呼べないか調べる
→テンプレート取得のタイミングを変えたい
backboneで書いたらスッキリ書けるかどうか調べる。