準備
依存ライブラリ
Backbone.jsはjQueryとunderscoreに依存しています。
準備を簡単にするために、各ライブラリをCDNから取得します。
<head>
<script src="https://code.jquery.com/jquery-2.2.2.js" integrity="sha256-4/zUCqiq0kqxhZIyp4G0Gk+AOtCJsY1TA00k5ClsZYE=" crossorigin="anonymous"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/underscore.js/1.8.3/underscore.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/backbone.js/1.3.2/backbone.js"></script>
</head>
RESTful API
typicode/jsonplaceholder: A simple fake REST API serverを使います。
npm install -g jsonplaceholder
jsonplaceholder
http://localhost:3000/posts/1 からリソースを取得します。
完成画面
ES2015を使っています。
- Const
- Arrow Functions
- Template Strings
- Enhanced Object Literals
次のブラウザで動きます。
- Google Chrome 49.0.2623.87
- Firefox 44.0.2
Safari 9.0.3では動きません。
ソースコード
<head>
<script src="https://code.jquery.com/jquery-2.2.2.js" integrity="sha256-4/zUCqiq0kqxhZIyp4G0Gk+AOtCJsY1TA00k5ClsZYE=" crossorigin="anonymous"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/underscore.js/1.8.3/underscore.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/backbone.js/1.3.2/backbone.js"></script>
<style>
body {
font-size: 1.1em;
}
input {
font-size: 100%;
width: 700px;
}
textarea {
font-size: 100%;
height: 100px;
width: 700px
}
button {
font-size: 100%;
}
</style>
</head>
<body>
<script>
const PostModel = Backbone.Model.extend({
url: 'http://localhost:3000/posts/1'
}),
PostView = Backbone.View.extend({
events: {
'click button': function() {
this.model
.set({
title: this.$('input').val(),
body: this.$('textarea').val()
})
.save()
}
},
initialize() {
this.model.on('change', () => this.render())
},
render() {
const json = this.model.attributes,
html =
`
<div>title:</div>
<input value="${json.title}">
<div>body:</div>
<textarea>${json.body}</textarea>
<div>
<button>押す</button>
</div>
`
this.$el.html(html)
}
}),
postModel = new PostModel(),
postView = new PostView({
model: postModel
})
$('body').append(postView.$el)
postModel.fetch()
</script>
</body>
解説
PostModel
Backbone.js の Model.fetch で RESTful API から情報取得 と同じです。
url
をローカルアドレスに変更しています。
PostView
eventsハッシュマップ
events: {
'click button': function() {
this.model
.set({
title: this.$('input').val(),
body: this.$('textarea').val()
})
.save()
}
},
ボタンクリック時のイベントハンドラーを定義します。
thisでPostViewインスタンスを参照するため、アロー関数は使えません。
views with declarative event handling
の部分です。
initialize関数
initialize() {
this.model.on('change', () => this.render())
},
初期化処理です。
モデルのchange
イベントに応じてrender
関数を実行します。
アロー関数なので、thisはinitialize関数実行時のthis、つまりPageViewのインスタンスです。
次のように、無名関数を使うと
this.model.on('change', function (){ this.render() })
thisはchange
イベントのコールバック関数実行時のthis、つまりPageModelのインスタンスになり上手くうごきません。
http://backbonejs.org/#View-extend では
this.listenTo(this.model, "change", this.render)
を推奨しています。
If the view defines an initialize function, it will be called when the view is first created.
initialize関数はインスタンス生成時に実行されます。より正確には、
var View = Backbone.View = function(options) {
this.cid = _.uniqueId('view');
_.extend(this, _.pick(options, viewOptions));
this._ensureElement();
this.initialize.apply(this, arguments);
};
コンストラクタの最後で実行されます。
initialize: function(){},
initialize関数が定義されていない場合は空関数が実行されます。
render関数
render() {
const json = this.model.attributes,
html =
`
<div>title:</div>
<input value="${json.title}">
<div>body:</div>
<textarea>${json.body}</textarea>
<div>
<button>押す</button>
</div>
`
this.$el.html(html)
}
this.model.attributes
からモデルの値を取得します。
Template Stringsを使ってhtml文字列を作成します。
jQuery.htmlを使って、自身の要素にhtml文字列を追加します。
main処理
postModel = new PostModel(),
postView = new PostView({
model: postModel
})
$('body').append(postView.$el)
postModel.fetch()
PostModelのインスタンスを作ります。
modelとしてPostModelのインスタンスを指定して、PostViewのインスタンスを作ります。
PostViewのインスタンスの$el
プロパティに、作成したDOMのjQueryオブジェクトが入っています。
bodyに追加します。
PostModelのインスタンスのfetch
メソッドで、RESTful APIから値を取得します。