みなさんこんにちは。
最近はやっとJavaScriptをがっつりいじることが出来そうになったので、Backbone.jsに入門してみました。 また、CoffeeScriptも便利だと聞いたのでこれも勉強してみました。
勉強のためにドットインストールで公開されているBackbone.js入門の完成品を参考に、JavaScriptのコードをCoffeeScriptで書きなおしました。
これからCoffeeScriptを勉強しようと思っている人に少しでも役に立てればと思います。
CoffeeScriptもやり始めて1日くらいしかたってないので、ここはCoffeeだとこんな感じに書けるよ!とかあれば教えていただけると幸いですー ドットインストール便利!いつもお世話になってます!
また、動作環境は以下になります。
| CoffeeScript | v1.6.3 |
| Backbone.js | v1.0.0 |
| jQuery | v1.8.3 |
| underscore.js | v1.4.3 |
app.coffeeのコード
以下が今回書きなおしたCoffeeScriptのコードです! コンパイルすればapp.jsが生成されるのでそれを下のindex.htmlに読みこめば使えるはずです。
app.coffee
jQuery ->
class Task extends Backbone.Model
defaults:
title: 'do something'
completed: false
validate: (attrs) ->
if _.isEmpty attrs.title
'title must not be empty!'
initialize: ->
@on 'invalid', (model, error) ->
$('#error').html error
class Tasks extends Backbone.Collection
model: Task
class TaskView extends Backbone.View
tagName: 'li'
initialize: ->
@model.on 'destroy', @remove, @
@model.on 'change', @render, @
events:
'click .delete': 'destroy'
'click .toggle': 'toggle'
toggle: ->
@model.set 'completed', !@model.get 'completed'
destroy: ->
if confirm 'are you sure?'
@model.destroy()
remove: ->
@.$el.remove()
template: _.template($('#task-template').html())
render: ->
template = @template @model.toJSON()
@.$el.html template
@
class TasksView extends Backbone.View
tagName: 'ul'
initialize: ->
@collection.on 'add', @addNew, @
@collection.on 'change', @updateCount, @
@collection.on 'destroy', @updateCount, @
addNew: (task) ->
taskView = new TaskView model: task
@.$el.append taskView.render().el
$('#title').val('').focus()
@updateCount()
updateCount: ->
uncompletedTasks = @collection.filter( (task) ->
!task.get 'completed'
)
$('#count').html uncompletedTasks.length
@
render: ->
@collection.each (task) ->
taskView = new TaskView model:task
@.$el.append taskView.render().el
, @
@updateCount()
class AddTaskView extends Backbone.View
el: '#addTask'
events:
'submit': 'submit'
submit: (e) ->
e.preventDefault()
task = new Task
if task.set( {title: $('#title').val()}, {validate: true} )
@collection.add task
$('#error').empty()
tasks = new Tasks([
{
title: 'task1'
completed: true
}
{
title: 'task2'
}
{
title: 'task3'
}
])
tasksView = new TasksView collection: tasks
addTaskView = new AddTaskView collection: tasks
$('#tasks').html tasksView.render().el
index.htmlのコード
index.htmlのコードは以下です! jqueryとかbackboneとかunderscoreは上のほうにバージョン番号が書いてあるのでそれに合わせて読み込んでくださいー!
index.html
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<title>Backbone.js sample</title>
<style>
.completed {
text-decoration: line-through;
color: gray;
}
</style>
</head>
<body>
<h1>Tasks</h1>
<form id="addTask">
<input type="text" id="title">
<input type="submit" value="add">
<span id="error"></span>
</form>
<div id="tasks"></div>
<p>Tasks left: <span id="count"></span></p>
<script type="text/template" id="task-template">
<input type="checkbox" class="toggle" <%= completed ? 'checked' : '' %>>
<span class="<%= completed ? 'completed' : '' %>">
<%- title %>
</span>
<span class="delete">[x]</span>
</script>
<script src="js/underscore.js"></script>
<script src="js/jquery.js"></script>
<script src="js/backbone.js"></script>
<script src="js/coffee.js"></script>
</body>
</html>
app.coffeeに書きなおす際に困ったこと
今回Coffeeの文法をやったあとに書きなおしてみたんですが、困ったことと言えば
- jQueryの関数の()を省略しちゃって動かない
- jQueryでDOMをいじったあとに「@」を書かないと動かない
ってことくらいです。それ以外は結構さらさら書けました。
Coffeeだと()が省略出来るからといって、jQueryの関数まで省略しちゃダメです(´;ω;`) 具体的には35〜37行目の部分とか39〜40行目の部分とかです。
35〜37行目
destroy: ->
if confirm 'are you sure?'
@model.destroy()
39〜40行目
remove: ->
@.$el.remove()
また、Coffeeだと関数内で最後に評価されたものがreturnされてしまうので、DOMをいじったあとそのままにしちゃうとそのDOMをreturnしちゃうのでそこで謎のエラーが起きるってことがありました。 具体的には65〜69行目の部分。
updateCount: ->
uncompletedTasks = @collection.filter( (task) ->
!task.get 'completed'
)
$('#count').html uncompletedTasks.length
@
最後に
やっぱCoffeeScriptって便利ですね! 書きなおした際も、元のapp.jsだと200行程度になるんですが、CoffeeScriptで書きなおすと100行程度におさまりました。 あとCoffeeで書いたほうが見やすい! これは癖になるのもわかります。 これからBackbone.jsとかCoffeeScriptとかもっと勉強していこーと思います! 質問やこうしたほうがいいよーっていうのがあれば@DAI199までリプライお願いします!