狠狠撸

狠狠撸Share a Scribd company logo
jsCafe7(2013/5/19)

introduction to
Backbone.js with Parse.com
Ryuma Tsukano

×
趣旨

BackboneのMV*とは何か?
実際のsourceを作って全体を把握するのが目的

※単にアプリ作っても面白くないのでParseというBaaS使う
目次
●
●
●
●

BackboneのMV*構成
Parse.com
tutorial
ソース振り返り
Backboneの基本構成
Router

HTTP Request

model更新

Collection
Models

View
modelイベント
html描写

syncs
DOM
イベント

Template

Data Source
(ex:DB/API)

サーバー側
BackboneのMV*
● model
○ データとそれに関するビジネスロジックを扱う。

● collection
○ 複数のデータの集合。ソートや集計等を扱う。

● view
○ ロジックがあり再利用可能なUIの小片。

● router
○ urlと関数の関連付けを行う。

● template
○ htmlの小片。
これから
よくあるToDOアプリを作ります

そして、
単に書くだけでは面白くないので....
笔补谤蝉别使う
Parseとは
BaaS(Backend as a Service):クラウドサービス
● 要するに以下をやってくれる
○ Backend側プログラム
■ Restに沿って独自APIを事前に準備
●

※今迄rails等で書いていた物がParse側で準備されている

○ storage
■ 非公式だがcouchDBという噂が。
●

※今迄mySQL等構築していた物がParse側で準備されてる

○ 今は、色々出来る事が増えてるみたい
■ 認証?/analytics?/push通信?
■ 最近hostingも始まった。
つまり
開発者はClient側だけ作れば良い
○ Web : front側だけ
○ スマホ : native側だけ

● 色んなシチュエーションで使えそう
○
○
○
○

開発者いないけどDBにデータ入れたい
個人開発スマホアプリで気軽にdata保存したい
とりあえずモック作りたい
勿論、実際の製品に使ってる例も沢山有り
イメージ
注意:構成は非公開なのでimage

Rest API

CRUD操作等

json
Client

Web/App
Server

NoSQL
っぽい何か
事例
● 山のようにある
○ スマホアプリで多く使われている
○ 日本でも事例ちらほら。
ちなみに

Facebookに買収されたらしい(2013/4月末)
● とっても未来のあるサービス
Client
沢山ある。
● iOS版
● Android版
● .NET版
● javascript版 ★これからこれを使う★
○ Backbone.jsベース(古いBackboneのfork)
■ 少しだけ記述が違う
●
●
●

Backbone.Model => Parse.Object
Backbone.Collection => Parse.Collection
Backbone.View => Parse.View

●

基本的にBackboneをParseにすれば良いが、Modelだけ
Objectになってる点、注意。
sample手順
1. ユーザー登録
○ sign upでメアド登録

2. Dashboardでアプリ作成(create New App)
3. QuickStartGuide をclick
○ ①javascript選択
○ ②new project選択
○ ③Blank?Parse SDK(zip)をdownload

4. 解凍後index.htmlのParse.initializeを置換
これでコピペ
5. index.htmlをbrowser確認
○

We’ve also just created...=>成功
index.html見てみる
● 以下を保存
○ TestObject(Excelシート/tableみたいな物)
○ foo : bar (列と値/カラムと値みたいな物)
Parse.initialize("APPLICATION_ID", "JAVASCRIPT_KEY");
var TestObject = Parse.Object.extend("TestObject");
var testObject = new TestObject();
testObject.save({foo: "bar"}, {
success: function(object) {
$(".success").show();
},
error: function(model, error) {
$(".error").show();
}
});
index.htmlのhead見てみる
● parse-x.x.x.min.jsを呼んでる
○ Backboneをwrapしたjsファイル
○ storageのsync先がParseになってる
<script type="text/javascript" src=/ryumatsukano/introduction-backbone-parse-reedit/"http:/ajax.googleapis.
com/ajax/libs/jquery/1.7.2/jquery.min.js"></script>
<script type="text/javascript" src="http://www.parsecdn.
com/js/parse-1.2.12.min.js"></script>
ついでに
dev tool見てみると
※送信時に
● api.parse.comと通信
● 箩蝉辞苍が返ってきてる
データオブジェクト
Parse.comのdashboardでdataを確認できる
ToDoApps
今日作るToDoアプリの構成
● サーバー/ストレージ
○ ToDoのCRUD
■ Parseに記録

● クライアント
○ 表示/Event
■ Backbone.jsを使う
●
●

但し本物のBackbone.jsではなく
Parse-x-x-x.min.jsでwrapされたもの(少しだけ仕様違う)
tutorial
1.
2.
3.
4.
●

HTML準備
Model作成
Collection作成
View作成
先程のsampleのindex.htmlをベースに
○ ※実際はそれぞれfileを分けるが今日は1fileで
HTML準備
10行付近jQuery前:underscore.jsを追加
<script type="text/javascript" src=/ryumatsukano/introduction-backbone-parse-reedit/"http:/underscorejs.org/underscore.js"
></script>

20行付近div#main:中身を削除。以下上書。
<div id="main">
<form id="todo-form">
<input type="text" id="title"/>
<input type="submit"/>
</form>
<div id="error"></div>
<div id="todo-list">
<ul></ul>
</div>
</div>

フォーム
バリデーション
表示領域

<span class='help' style="display:none;">text入れて送信するだけね<a href='#'>戻る</a></span>
キーを指定
● scriptタグ内はParse.initialize以外削除
○ ※APP_ID/JS_KEYは先程のをそのまま使って

<script type="text/javascript">
Parse.initialize("APP_ID", "JS_KEY");
// ここに以降、追加していきます
</script>
Model作成
● Parse.Object(=Backbone.model)
○ 特にschema定義不要(schemaless)
○ validation:値の検証
■ 今回:空白をcheck!

var Todo = Parse.Object.extend({
className:"Todo",
validate: function(attrs){
if(_.isEmpty(attrs.title)){
return "please write text!";
}
}
});
Collection作成
● Parse.Collection(=Backbone.Collection)
○ Todoモデルを束ねる
○ ソート等書く

var TodoList = Parse.Collection.extend({ model: Todo });
今回のView構成
● 結果表示
○ ①TodoView : Todoの1つ(liの中)
○ ②TodoListView : 複数のTodoの一覧(ul)

● フォーム
○ ③TodoFormView : 送信をcheck

● 全体
○ ④AppView : 初期処理
■ 各View準備
■ Parseからdata読取

③
①
②
View作成(①:1つのtodo)
● Parse.View(=Backbone.View)
○
○
○
○

tagName: このViewを囲うtag
template : htmlのテンプレート(後述)
render : 描写処理を書く関数
el : 対象要素

var TodoView = Parse.View.extend({
tagName: "li",
template: _.template($('#todo-template').html()),
render: function(){
this.$el.html(this.template(this.model.toJSON()));
return this;
}
});
View作成 : template
● templateは、scriptタグで外に出せる(後述)
○ 先程のtemplateから呼び出している
○ jsp等と同じように変数を埋め込める(title)

● このtemplateを①のViewが描写している
<script type="text/template" id="todo-template">
<strong>[TODO]</strong>
<span><%- title %></span>
</script>
View作成(②:複数のtodo)
● Parse.View(Backbone.View.extend)
○ el : 対象要素(どこに描写するか指定)
○ initialize : 初期処理
■ collectionにadd
var TodoListView = Parse.View.extend({
el: "#todo-list > ul",
■ =>render
initialize: function(){
○ render:描写処理
this.collection.on("add", this.render, this);
},
■ collectionループ
render: function() {
■ 自分の要素内に
this.$el.html("");
this.collection.each(function(todo) {
■ ①のViewを描写

var todoView = new TodoView({model:todo});
this.$el.append(todoView.render().el);
},this);
return this;

}
});
View作成(③:フォーム)
● Parse.View(Backbone.View.extend)
○ events : イベント
■ submitあったら、
■ createTodo関数を実行
○ createTodo : オリジナル関数
■ inputタグからTodoを作成
■ error時は#errorにmessage
●

先程のvalidationここで表示

■ validationで問題なければ
●
●

Todoを保存
成功したらcollectionに追加

var TodoFormView = Parse.View.extend({
el: "#todo-form",
events: {
"submit": "createTodo"
},
createTodo: function(e) {
e.preventDefault();
var todo = new Todo();
todo.on('error', function(model, error)
{$('#error').html(error);});
todo.set({title : $('#title').val()})
if(todo.isValid()) {
$('#error').html('');
todo.save(null, {
success: _.bind(function(todo) {
this.collection.add(todo);
$('#title').val('');
}, this)
});
};
}
});
View作成(④:アプリ全体)
● 初期処理
○ Parse.Query(class名).findでParseから一覧取得
○ 各View(②list③form)を初期化して準備
■ ②listは、Parseのdataを表示
var AppView = Parse.View.extend({
initialize: function(){
new Parse.Query("Todo").find({
success: _.bind(function(list){
var todoList = new TodoList(list);
var todoFormView = new TodoFormView({collection: todoList});
this.todoListView = new TodoListView({collection: todoList});
this.render();
}, this)
});
},
render: function(){
this.todoListView.render();
return this;
}
});
Router作成
● Parse.Router(=Backbone.Router)
○ initialize
■ ④初期View準備
○ routes:URLと関数を紐付け
■ URL:#help(アンカー)
■ help関数実行
●

help用のhtml表示

○ raisのconfig/routes.rb的な物
○ history.start
■ routeのdispatchを開始

var TodoRouter = Parse.Router.extend({
initialize: function(){
var appView = new AppView();
},
routes: {
"help" : "help",
"" : "show"
},
help : function() {
$('#main').hide();
$("span.help").show();
},
show : function() {
$("span.help").hide();
$('#main').show();
}
});
var todoRouter = new TodoRouter;
Parse.history.start();
これで終わり
動いてる?
● 動かない人=>githubに上げておいた
ソースを見ると
● 全体
○ データ(M)と表示処理(V)が分かれている
■ データに対してのロジックなのか、画面描写に関して
の処理なのか明確に
○ Viewも1画面の中でUIの構成要素毎に分かれている
■ DOMのEventがごちゃごちゃしない。

少し長いソースになったけど、
何やってるかは分かり易いソースになった。
Modelについて
● 特にスキーマを定義しない
● 1つと複数とをmodel/collectionで分ける
○ 例)Twitterで言うと
■ userがmodel
■ follower/followがcollection

● 実際Backboneを使う時はurlを指定してREST
のルールに従ってデータを送受信
Viewについて
普通のバックエンドのViewと少し違う
● BackboneのView=表示用のlogicを含む。
○ rails等backendのView = erb/jsp等templateだが

● Viewのソースを見ると
○ DOMとEventの紐付きが分かり易い
○ 画面描写何してるかはrender見れば何となく分かる
○ よくある文字リテラルによるhtml作成でなく、template使
うのでどんな画面になるかimageし易い
router
urlのアンカーに対応して関数実行
● 別画面、tab、popup等用途色々ありそう
● single page application用途
#

#help
基本構成をもう一度
Router

HTTP Request

model更新

Collection
Models

View
modelイベント
html描写

syncs
DOM
イベント

Template

Data Source
(ex:DB/API)

サーバー側
おしまい

More Related Content

笔补谤蝉别.肠辞尘と始める叠补肠办产辞苍别.箩蝉入门(箩蝉肠补蹿别7)