第4回rest勉強会 requirejs編
TRANSCRIPT
機能や役割ごとの 「かたまり」
var app = app || {}; (function(app) { app.Application = Backbone.Marionette.Application.extend({ 〜 中略 〜 }); })(app);
app.js
機能や役割ごとの 「かたまり」
var app = app || {}; (function(app) { app.Application = Backbone.Marionette.Application.extend({ 〜 中略 〜 }); })(app);
app.js
•「Backbone/Marionetteを継承したオブジェクトをappオブジェクトに突っ込む」 •「new app.Application()」などと利用する
appオブジェクトの中の 「かたまり」を見てみる
var app = app || {}; //開始 (function(app) { app.application = new app.Application(); app.application.start(); console.log(app); // appオブジェクトをログ出力 })(app);
main.js
最初にドカンと 読み込んでいます
<!-- js(library) --> <script src="js/lib/jquery-2.1.3.min.js" type="text/javascript"></script> <script src="js/lib/underscore-min.js" type="text/javascript"></script> <script src="js/lib/backbone-min.js" type="text/javascript"></script> <script src="js/lib/backbone.marionette.min.js" type="text/javascript"></script>
<!-- js(application) --> <!-- model --> <script src="js/models/todo-model.js" type="text/javascript"></script> <!-- collection --> <script src="js/collections/todo-collection.js" type="text/javascript"></script> <!-- view --> <script src="js/views/todo-item-view.js" type="text/javascript"></script> <script src="js/views/todo-detail-item-view.js" type="text/javascript"></script> <script src="js/views/todo-detail-layout-view.js" type="text/javascript"></script> 〜以下略〜
default.ctp(抜粋)
順番重要!<!-- js(library) --> <script src="js/lib/jquery-2.1.3.min.js" type="text/javascript"></script> <script src="js/lib/underscore-min.js" type="text/javascript"></script> <script src="js/lib/backbone-min.js" type="text/javascript"></script> <script src="js/lib/backbone.marionette.min.js" type="text/javascript"></script>
<!-- js(application) --> <!-- model --> <script src="js/models/todo-model.js" type="text/javascript"></script> <!-- collection --> <script src="js/collections/todo-collection.js" type="text/javascript"></script> <!-- view --> <script src="js/views/todo-item-view.js" type="text/javascript"></script> <script src="js/views/todo-detail-item-view.js" type="text/javascript"></script> <script src="js/views/todo-detail-layout-view.js" type="text/javascript"></script> 〜以下略〜
default.ctp(抜粋)
例) Backboneが先 Marionetteが後⇢「依存関係」
順番重要!<!-- js(library) --> <script src="js/lib/jquery-2.1.3.min.js" type="text/javascript"></script> <script src="js/lib/underscore-min.js" type="text/javascript"></script> <script src="js/lib/backbone-min.js" type="text/javascript"></script> <script src="js/lib/backbone.marionette.min.js" type="text/javascript"></script>
<!-- js(application) --> <!-- model --> <script src="js/models/todo-model.js" type="text/javascript"></script> <!-- collection --> <script src="js/collections/todo-collection.js" type="text/javascript"></script> <!-- view --> <script src="js/views/todo-item-view.js" type="text/javascript"></script> <script src="js/views/todo-detail-item-view.js" type="text/javascript"></script> <script src="js/views/todo-detail-layout-view.js" type="text/javascript"></script> 〜以下略〜
default.ctp(抜粋)
例) Backboneが先 Marionetteが後⇢「依存関係」
めんどくさい!
依存関係
function Hoge(){ var fuga = new Fuga(); . . .
}
hoge.js
function Fuga(){ var piyo = new Piyo(); . . .
}
fuga.js
function Piyo(){ . . . }
piyo.js
依存関係
function Hoge(){ var fuga = new Fuga(); . . .
}
hoge.js
function Fuga(){ var piyo = new Piyo(); . . .
}
fuga.js
function Piyo(){ . . . }
piyo.js
HogeはFugaを必要とする FugaはPiyoを必要とする
依存関係
function Hoge(){ var fuga = new Fuga(); . . .
}
hoge.js
function Fuga(){ var piyo = new Piyo(); . . .
}
fuga.js
function Piyo(){ . . . }
piyo.js
Hoge Requires Fuga Fuga Requires Piyo
function Hoge(){ var fuga = new Fuga(); . . .
}
hoge.js
function Fuga(){ var piyo = new Piyo(); . . .
}
fuga.js
function Piyo(){ . . . }
piyo.js
モジュール間の依存関係を解決
function Hoge(){ var fuga = new Fuga(); . . .
}
hoge.js
function Fuga(){ var piyo = new Piyo(); . . .
}
fuga.js
function Piyo(){ . . . }
piyo.js
モジュール間の依存関係を解決
•Require.js流モジュール形式にすることで、モジュール自身が依存ファイルを取得する •それ以外(jquery等)は設定で解決
Require.js流モジュール形式define(function(require) { var TodoModel = require('models/todo-model');
var TodoCollection = Backbone.Collection.extend({ url : '/rest-study/todo_lists.json', model : TodoModel,
parse : function(response) { //コレクションをパース console.log("コレクションをパース"); return response; } }); return TodoCollection; });
サンプル(todo-collection.js)
gitのブランチを整える
■masterブランチを前回の終了状態にする
■masterブランチを元に、今回の作業用である、 「vol/04」ブランチを作成する
※作業の過程で、今回の内容を終えた状態の “解答ブランチ”である、 「vol/04-finish」ブランチも取得されます。
どう整えるのか
gitのブランチを整える
人によってやり方が違います!(重要)
■前回の内容を完了した方 ⇢vol/03ブランチが綺麗に完了済み!
■前回の内容を途中までやった方 ⇢vol/03ブランチが編集途中の状態
■今回から参加の方 (第1回勉強会の内容は終えている状態) ⇢vol/03ブランチは作っていない!
gitのブランチを整える
鈴木商店GitHubを リモートリポジトリとして追加する
第1回で、鈴木商店GitHubからforkしました。 「鈴木商店GitHub」を「リモートリポジトリ」 として登録する作業です。
gitのブランチを整える
origin upstream ←これがあればOK!
鈴木商店GitHubをリモートリポジトリとして追加する
git remote
とやって、下記が表示される人は既にこの作業が終わっています。次へ行きましょう。
gitのブランチを整える
git remote add upstream https://github.com/suzukishouten-study/rest-study.git
鈴木商店GitHubをリモートリポジトリとして追加する
コマンド (実際は一行です)
鈴木商店GitHub https://github.com/suzukishouten-study/rest-study.git を、リモートリポジトリ名 「upstream」 として登録する作業です。
鈴木商店 勉強会用GitHubリポジトリ
master
vol/04-finish
vol/01-finish
EC2インスタンス
作業用として使用 master
vol/04-finish
vol/01-finish
vol/03
vol/01
vol/04
ローカルリポジトリ
gitのブランチを整えるイメージ
upstream
自分の GitHubリポジトリ
master
vol/03
vol/01
originclone時に自動登録
これを登録!
~
~
~~
gitのブランチを整える
鈴木商店GitHubから最新のコミットを取得する前回の終了状態である 「vol/03-finish」ブランチを ローカルリポジトリに取得する作業です。 ※今回の終了状態として事前に用意した、 「vol/04-finish」ブランチも取得されます。
gitのブランチを整える
次の手順は注意!■前回の内容を完了した方
■前回の内容を途中までやった方と今回から参加の方
ローカルリポジトリのvol/03 ブランチをmasterブランチにマージ
upstreamリポジトリのvol/03-finish ブランチをmasterブランチにマージ
gitのブランチを整える
git checkout masterコマンド
■前回の内容を完了した方
続いて、
git merge vol/03
ローカルリポジトリのvol/03 ブランチをmasterブランチにマージ
gitのブランチを整える
git checkout masterコマンド
続いて、
git reset --hard upstream/vol/03-finish
■前回の内容を途中までやった方と今回から参加の方
upstreamリポジトリのvol/03-finish ブランチをmasterブランチにマージ
gitのブランチを整える
git branch vol/04コマンド
続いて、
git checkout vol/04
今回の作業用である、 「vol/04」ブランチを作成する
これでブランチ作成、チェックアウトまで完了!
RequireJSライブラリダウンロード
ダウンロード先ディレクトリ
ココ
/var/www/study/rest-study/ ├── app │ ~略~ │ └── webroot │ ├── css │ ├── files │ ├── img │ └── js │ ├── collections │ ├── lib │ ├── models │ ├── routers │ └── views
/var/www/study/rest-study/app/webroot/js/lib
wget http://requirejs.org/docs/release/2.1.17/minified/require.js
ダウンロード元(RequireJS公式サイト)http://requirejs.org/docs/release/2.1.17/minified/require.js
wgetコマンドでダウンロード
require流モジュール形式サンプル(todo-collection.js)define(function(require) { var TodoModel = require('models/todo-model');
var TodoCollection = Backbone.Collection.extend({ url : '/rest-study/todo_lists.json', model : TodoModel,
parse : function(response) { //コレクションをパース console.log("コレクションをパース"); return response; } }); return TodoCollection; });
define(function(require) { var TodoModel = require('models/todo-model');
var TodoCollection = Backbone.Collection.extend({ url : '/rest-study/todo_lists.json', model : TodoModel,
parse : function(response) { //コレクションをパース console.log("コレクションをパース"); return response; } }); return TodoCollection; });
依存ファイルサンプル(todo-collection.js)
これに依存している
define(function(require) { var TodoModel = require('models/todo-model');
var TodoCollection = Backbone.Collection.extend({ url : '/rest-study/todo_lists.json', model : TodoModel,
parse : function(response) { //コレクションをパース console.log("コレクションをパース"); return response; } }); return TodoCollection; });
依存ファイルを先に読み込むサンプル(todo-collection.js)
読み込む
これに依存している
define(function(require) { var TodoModel = require('models/todo-model');
var TodoCollection = Backbone.Collection.extend({ url : '/rest-study/todo_lists.json', model : TodoModel,
parse : function(response) { //コレクションをパース console.log("コレクションをパース"); return response; } }); return TodoCollection; });
依存モジュールを受け取るサンプル(todo-collection.js)
読み込んだモジュールが 取得される
define(function(require) { var TodoModel = require('models/todo-model');
var TodoCollection = Backbone.Collection.extend({ url : '/rest-study/todo_lists.json', model : TodoModel,
parse : function(response) { //コレクションをパース console.log("コレクションをパース"); return response; } }); return TodoCollection; });
依存されているモジュールの為にreturnサンプル(todo-collection.js)
生成したモジュールをreturnすることで他から利用できる
ファイルのpathを定義 paths : { 'jquery' : 'lib/jquery-2.1.3.min', 'underscore' : 'lib/underscore-min', 'backbone' : 'lib/backbone-min', 'marionette' : 'lib/backbone.marionette.min', }
paths変数
ファイルの依存関係を定義 shim : { 'jquery' : { exports : '$' }, 'underscore' : { deps : ['jquery'], exports : '_' }, 'backbone' : { deps : ['jquery', 'underscore'], exports : 'Backbone' }, 'marionette' : { deps : ['backbone'], exports : 'Marionette' }, }
require流モジュール形式でない物のみ
設定する
shim変数
■require-config.jsを読み込む ■require.jsを読み込むdefault.ctp
<script type="text/javascript" src="js/require-config.js"></script> <script type="text/javascript" src="js/lib/require.js" data-main="main.js"></script>
1.require-config.js 2.require.js の順に読み込むdata-main属性で指定したファイルがエントリポイントとなる
■require関数で読み込むmain.js (エントリポイント)
//開始 require(['marionette'],function(){ require(['app'], function(Application){ window.application = new Application(); window.application.start(); }); });
■console.log()を仕込むmain.js (エントリポイント)
//開始 console.log('load main'); require(['marionette'],function(){ console.log('run main'); require(['app'], function(Application){ console.log('run main2'); window.application = new Application(); window.application.start(); console.log('app start'); }); });
app.js
define( function(require){ var Router = require('routers/router'); var Application = Marionette.Application.extend({ initialize : function(){ console.log('app.initialize'); new Router(); }, onStart : function(){ Backbone.history.start(); }, regions : { mainRegion : '#main' } }); return Application; } );
■define関数でモジュールを定義する
app.jsconsole.log('load app'); define( function(require){ console.log('run app'); var Router = require('routers/router'); var Application = Marionette.Application.extend({ initialize : function(){ console.log('app.initialize'); new Router(); }, onStart : function(){ Backbone.history.start(); }, regions : { mainRegion : '#main' } }); return Application; } );
■同じくconsole.log()を仕込む
■require関数 と define関数
require(['marionette'],function(){ 〜処理〜 });
main.js (エントリポイント)
読み込んで処理実行のみ ⇢ require()
■require関数 と define関数
require(['marionette'],function(){ 〜処理〜 });
main.js (エントリポイント)
app.jsdefine(function(require){
var Router = require('routers/router'); return モジュール; });
読み込んで処理実行のみ ⇢ require()
■require関数 と define関数
require(['marionette'],function(){ 〜処理〜 });
main.js (エントリポイント)
app.jsdefine(function(require){
var Router = require('routers/router'); return モジュール; });
読み込んでモジュール定義 ⇢ define()
読み込んで処理実行のみ ⇢ require()
main.js (エントリポイント)
//開始 require(['marionette'],function(){ require(['app'], function(Application){ window.application = new Application(); window.application.start(); }); });
■require()
functionの中は、実行しているだけでreturnは無し
app.jsdefine( function(require){ var Router = require('routers/router'); var Application = Marionette.Application.extend({ initialize : function(){ console.log('app.initialize'); new Router(); }, onStart : function(){ Backbone.history.start(); }, regions : { mainRegion : '#main' } }); return Application; } );
■define()
Applicationオブジェクトを生成してreturnしている
■viewの読み込みはrequire()でcontroller.js(抜粋)
var TodoController = Marionette.Controller.extend({ todoLists : function() { //Todoレイアウト用ビューにルーティング this.nextView('views/todo-layout-view'); },
todoDetail : function(id) { this.nextView('views/todo-detail-layout-view', {modelId : id}); },
nextView : function(viewPath, option) { require([viewPath], function(View){ window.application.mainRegion.show(new View(option)); }); }, });
■viewの読み込みはrequire()でcontroller.js(抜粋)
var TodoController = Marionette.Controller.extend({ todoLists : function() { //Todoレイアウト用ビューにルーティング this.nextView('views/todo-layout-view'); },
todoDetail : function(id) { this.nextView('views/todo-detail-layout-view', {modelId : id}); },
nextView : function(viewPath, option) { require([viewPath], function(View){ window.application.mainRegion.show(new View(option)); }); }, });
viewファイルの pathを指定
■viewの読み込みはrequire()でcontroller.js(抜粋)
var TodoController = Marionette.Controller.extend({ todoLists : function() { //Todoレイアウト用ビューにルーティング this.nextView('views/todo-layout-view'); },
todoDetail : function(id) { this.nextView('views/todo-detail-layout-view', {modelId : id}); },
nextView : function(viewPath, option) { require([viewPath], function(View){ window.application.mainRegion.show(new View(option)); }); }, });
viewファイルの pathを指定
require()で読み込み
application.start()までの流れmain.js 開始 各ライブラリに依存 marionette読み込み⇢ backbone.marionette.min.js
backbone-min.js
application.start()までの流れmain.js 開始 各ライブラリに依存 marionette読み込み⇢ backbone.marionette.min.js
backbone-min.js underscore-min.js
application.start()までの流れmain.js 開始 各ライブラリに依存 marionette読み込み⇢ backbone.marionette.min.js
backbone-min.js underscore-min.js
jquery-2.1.3.min.js
application.start()までの流れmain.js 開始 各ライブラリに依存 marionette読み込み⇢ backbone.marionette.min.js
backbone-min.js underscore-min.js
jquery-2.1.3.min.js
app.jsに依存 読込み⇢
application.start()までの流れmain.js 開始 各ライブラリに依存 marionette読み込み⇢ backbone.marionette.min.js
backbone-min.js underscore-min.js
jquery-2.1.3.min.js
app.jsに依存 読込み⇢ app.js 開始
application.start()までの流れmain.js 開始 各ライブラリに依存 marionette読み込み⇢ backbone.marionette.min.js
backbone-min.js underscore-min.js
jquery-2.1.3.min.js
app.jsに依存 読込み⇢ app.js 開始
router.jsに依存 読込み⇢
application.start()までの流れmain.js 開始 各ライブラリに依存 marionette読み込み⇢ backbone.marionette.min.js
backbone-min.js underscore-min.js
jquery-2.1.3.min.js
app.jsに依存 読込み⇢ app.js 開始
router.jsに依存 読込み⇢ router.js 開始
application.start()までの流れmain.js 開始 各ライブラリに依存 marionette読み込み⇢ backbone.marionette.min.js
backbone-min.js underscore-min.js
jquery-2.1.3.min.js
app.jsに依存 読込み⇢ app.js 開始
router.jsに依存 読込み⇢ router.js 開始
controller.jsに依存 読込み⇢
application.start()までの流れmain.js 開始 各ライブラリに依存 marionette読み込み⇢ backbone.marionette.min.js
backbone-min.js underscore-min.js
jquery-2.1.3.min.js
app.jsに依存 読込み⇢ app.js 開始
router.jsに依存 読込み⇢ router.js 開始
controller.jsに依存 読込み⇢
controller.js 開始
application.start()までの流れmain.js 開始 各ライブラリに依存 marionette読み込み⇢ backbone.marionette.min.js
backbone-min.js underscore-min.js
jquery-2.1.3.min.js
app.jsに依存 読込み⇢ app.js 開始
router.jsに依存 読込み⇢ router.js 開始
controller.jsに依存 読込み⇢
controller.js 開始function実行 (Controllerオブジェクト生成)
application.start()までの流れmain.js 開始 各ライブラリに依存 marionette読み込み⇢ backbone.marionette.min.js
backbone-min.js underscore-min.js
jquery-2.1.3.min.js
app.jsに依存 読込み⇢ app.js 開始
router.jsに依存 読込み⇢ router.js 開始
controller.jsに依存 読込み⇢
controller.js 開始function実行 (Controllerオブジェクト生成)
function実行 (Routerオブジェクト生成)
application.start()までの流れmain.js 開始 各ライブラリに依存 marionette読み込み⇢ backbone.marionette.min.js
backbone-min.js underscore-min.js
jquery-2.1.3.min.js
app.jsに依存 読込み⇢ app.js 開始
router.jsに依存 読込み⇢ router.js 開始
controller.jsに依存 読込み⇢
controller.js 開始function実行 (Controllerオブジェクト生成)
function実行 (Routerオブジェクト生成)
function実行 (Applicationオブジェクト生成)
application.start()までの流れmain.js 開始 各ライブラリに依存 marionette読み込み⇢ backbone.marionette.min.js
backbone-min.js underscore-min.js
jquery-2.1.3.min.js
app.jsに依存 読込み⇢ app.js 開始
router.jsに依存 読込み⇢ router.js 開始
controller.jsに依存 読込み⇢
controller.js 開始function実行 (Controllerオブジェクト生成)
function実行 (Routerオブジェクト生成)
function実行 (Applicationオブジェクト生成)
function実行 (application.start())
application.start()までの流れmain.js 開始 各ライブラリに依存 marionette読み込み⇢ backbone.marionette.min.js
backbone-min.js underscore-min.js
jquery-2.1.3.min.js
app.jsに依存 読込み⇢ app.js 開始
router.jsに依存 読込み⇢ router.js 開始
controller.jsに依存 読込み⇢
controller.js 開始function実行 (Controllerオブジェクト生成)
function実行 (Routerオブジェクト生成)
function実行 (Applicationオブジェクト生成)
function実行 (application.start())
ログを見て 確認しましょう!
template<body> <!-- コンテンツ --> <div id="main"></div>
<!-- TODO一覧表示のレイアウトテンプレート --> <script type="text/template" id="todo-layout-template"> <h1>TODOリスト</h1> <div id="todo-lists"></div> </script>
<!-- TODO一覧表示のテンプレート --> <script type="text/template" id="todo-composite-template"> <textarea style="width:300px;height:50px"id="new-todo" placeholder="Todo?" autofocus></textarea> <input type="button" id="addTodo" value="追加"> <hr> <div> <table border="1" width="350px"> <tbody></tbody> </table> </div> </script>
default.ctp(抜粋)