Backbone.js の見通しよくしてみる
のサンプルとして、Todosという小さめのサンプルがあるが、
http://backbonejs.org/examples/todos/index.html
これでもhtml部分で66行
script部分で245行ある。
見通しをよくして、backboneを理解してみる。
追記:Backboneのベタープラクティス的なパターン
http://ricostacruz.com/backbone-patterns
1. ViewのtagName
- http://backbonejs.org/#View-extend
- tagName, className, idによってrootエレメントを指定する。
- el
- http://backbonejs.org/#View-el
- すべてのViewは、elを持ち、elかtagName, className,idで指定される。
- http://documentcloud.github.com/underscore/#template
- _.template(templateString, [data], [settings])
- 第一引数:テンプレートのString
- render部に記載の、インスタンス化されたthis.template(モデル.toJSON)メソッドの第一引数は、_.templateメソッドの第二引数として遅延適用される。(カリー化?)
- http://backbonejs.org/#Events-on
- object.on(event, callback, [context])Alias: bind
- bindは、Eventのonメソッドのエイリアス
- 第一引数が、'add'であれば、onAddがコールされる
- 'all'は特別な引数、これはすべてのイベントでコールされる
HTML部
<!DOCTYPE html>
<html lang="en"><head>
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
<meta charset="utf-8">
<title>Backbone.js Todos</title>
<link rel="stylesheet" href="backborn_files/todos.css">
</head>
<body>
<div id="todoapp">
<header>
<h1>Todos</h1>
<input id="new-todo" placeholder="What needs to be done?" type="text">
</header>
<section id="main">
<ul id="todo-list"></ul>
</section>
</div>
<script src="backborn_files/json2.js"></script>
<script src="backborn_files/jquery-1.js"></script>
<script src="backborn_files/underscore-1.js"></script>
<script src="backborn_files/backbone.js"></script>
<script src="backborn_files/backbone-localstorage.js"></script>
<script src="backborn_files/minimum.js"></script>
<!-- Templates -->
<script type="text/template" id="item-template">
<div class="view">
<label><%- title %></label>
</div>
</script>
</body></html>
// An example Backbone application contributed by
// [Jérôme Gravel-Niquet](http://jgn.me/). This demo uses a simple
// [LocalStorage adapter](backbone-localstorage.js)
// to persist Backbone models within your browser.
// Load the application once the DOM is ready, using `jQuery.ready`:
$(function(){
// Todo Model
// ----------
// Our basic **Todo** model has `title`, `order`, and `done` attributes.
var Todo = Backbone.Model.extend({
// Ensure that each todo created has `title`.
initialize: function() {
localStorage.clear();
}
});
// Todo Collection
// ---------------
// The collection of todos is backed by *localStorage* instead of a remote
// server.
var TodoList = Backbone.Collection.extend({
// Reference to this collection's model.
model: Todo,
// Save all of the todo items under the `"todos"` namespace.
localStorage: new Store("todos-backbone")
});
// Create our global collection of **Todos**.
var Todos = new TodoList;
// Todo Item View
// --------------
// The DOM element for a todo item...
var TodoView = Backbone.View.extend({
//... is a list tag.
tagName: "li",
// Cache the template function for a single item.
template: _.template($('#item-template').html()),
// Re-render the titles of the todo item.
render: function() {
this.$el.html(this.template(this.model.toJSON()));
return this;
}
});
// The Application
// ---------------
// Our overall **AppView** is the top-level piece of UI.
var AppView = Backbone.View.extend({
// Instead of generating a new element, bind to the existing skeleton of
// the App already present in the HTML.
el: $("#todoapp"),
// Delegated events for creating new items, and clearing completed ones.
events: {
"keypress #new-todo": "createOnEnter"
},
// At initialization we bind to the relevant events on the `Todos`
// collection, when items are added or changed. Kick things off by
// loading any preexisting todos that might be saved in *localStorage*.
initialize: function() {
this.input = this.$("#new-todo");
Todos.bind('add', this.addOne, this);
Todos.bind('all', this.render, this);
this.main = $('#main');
Todos.fetch();
},
// Re-rendering the App just means refreshing the statistics -- the rest
// of the app doesn't change.
render: function() {
this.main.show();
},
// Add a single todo item to the list by creating a view for it, and
// appending its element to the `<ul>`.
addOne: function(todo) {
var view = new TodoView({model: todo});
this.$("#todo-list").append(view.render().el);
},
// If you hit return in the main input field, create new **Todo** model,
// persisting it to *localStorage*.
createOnEnter: function(e) {
if (e.keyCode != 13) return;
if (!this.input.val()) return;
Todos.create({title: this.input.val()});
this.input.val('');
}
});
// Finally, we kick things off by creating the **App**.
var App = new AppView;
});