Brunch(Backbone.js)の練習を兼ねて、Backbone.js で HTML の View と Model を分離してみるよのサンプルをBrunchで。
まずは、スケルトン作成
$ brunch new brtwitter
watchしつつ、ファイル更新を検知してコンパイルしつつ、サーバーを3333番portで起動する
$ cd brtwitter $ brunch watch --server [19:23:17]: [Brunch]: application starting on http://0.0.0.0:3333. [19:23:17]: [Brunch]: compiled.
あとはapp以下のファイルをいじる。
models/tweet.coffee
モデルをつくる。
class exports.Tweet extends Backbone.Model initialize: -> @set domId: "tweet_#{@cid}"
collections/tweet_list.coffee
コレクションを設定。ここまでは簡単
{Tweet} = require 'models/tweet' class exports.TweetList extends Backbone.Collection model: Tweet
views/tweet_list_view.coffee
{TweetView} = require 'views/tweet_view' {Tweet} = require 'models/tweet' tweetListTemplate = require './templates/tweet_list' class exports.TweetListView extends Backbone.View id: 'tweets-view' initialize: -> app.tweetList.bind 'add', @addOne $('body').append @render().el render: -> $(@el).html tweetListTemplate() @ addOne: (tweet) -> view = new TweetView model: new Tweet(tweet) $(@el).find('#tweets').prepend view.render().el
views/templates/tweet_list.eco
テンプレートは今回ecoをデフォルトのecoを使った。個人的にはjadeのほうが好きなのでそのうちJadeに乗り換える。
views/templates/tweet_list.eco
<ul id="tweets"></ul>
views/tweet_view.coffee
同様にtweetも
tweetTemplate = require('./templates/tweet') class exports.TweetView extends Backbone.View id: 'tweet-view' tagName: 'li' initialize: -> @model.view = this render: -> $(@el).html tweetTemplate tweet: @model.toJSON() @
views/templates/tweet.eco
<div class="twtr-avatar"> <div class="twtr-img"> <a href="http://twitter.com/intent/user?screen_name=<%= @tweet.from_user %>" target="_blank"> <img src="<%= @tweet.profile_image_url %>"> </a> <p><%= @tweet.text %></p> </div> </div>
assets/index.html
bodyタグの間に入れとく
<input id="searchTxt" type="text" value="backbone.js" /> <button id="searchBtn">search</button> <div id="tweetContainer">searchボタンを押すとTwitterから検索してくるよ!</div>
initialize.coffee
最後に初期化する。 {BrunchApplication} = require 'helpers' {MainRouter} = require 'routers/main_router' {TweetList} = require 'collections/tweet_list' {TweetListView} = require 'views/tweet_list_view' class exports.Application extends BrunchApplication initialize: -> @router = new MainRouter @tweetList = new TweetList @tweetListView = new TweetListView $("#searchBtn").click (e) -> jqxhr = $.ajax dataType: "jsonp" url: "http://search.twitter.com/search.json" data: { q: encodeURI( $( "#searchTxt" ).val() ) } jsonp: "callback" jqxhr.done (data) -> _.each data.results, (result) -> app.tweetListView.addOne(result) window.app = new exports.Application
ファイル構成はこんな感じ。home_*は必要ないけどスケルトンで作成されたのでそのまま放ってある。
. ├── assets │ ├── images │ └── index.html ├── collections │ └── tweet_list.coffee ├── helpers.coffee ├── initialize.coffee ├── models │ └── tweet.coffee ├── routers │ └── main_router.coffee ├── styles │ └── main.styl └── views ├── home_view.coffee ├── templates │ ├── home.eco │ ├── tweet.eco │ └── tweet_list.eco ├── tweet_list_view.coffee └── tweet_view.coffee
backbone.jsってviewがファットになんのね。