コンテンツ
- それでは始めましょう
- 私たちの最初のモデル
- 画像のコレクション
- FlickrBombImage
- ビューレイヤー
- FlickrBombImageView
- ホームストレッチ
- 大きな古いウェブアプリでもうまく機能します
- 追加のリソース
小さなJavaScriptツールをすばやく作成することを検討している場合は、フレームワークの使用を考えていない可能性があります。新しいフレームワークをインストールして学習するよりも、いくつかのjQueryコードを一緒にハックする方が簡単ですよね?間違って、Backbone.jsは超軽量の接着剤フレームワークであり、あなたが書いていた通常の古いJavaScriptと同じように見えます。
バックエンドコードを記述せずにページをクリックできるようにしたいので、ここZURBでは多くの静的プロトタイプを作成しています。多くの場合、ぼんやりとした灰色のプレースホルダー画像をドロップするか、Flickrでサンプル画像を検索して、最終ドラフトに何が含まれるかを視覚化するのに役立てることがありました。それは、ある魔法の金曜日までです。そのとき、問題を解決するためにJavaScriptを作成するのは素晴らしいことだと判断しました。プレースホルダー画像自体から直接、Flickrで写真を検索して選択できるようにしたかったのです。これをFlickrBombと呼びます。これは、Backbone.jsを使用して構築した方法の話です。
読む前に、FlickrBombをざっと見ることを強くお勧めします。これは、「クリックは千の言葉に値する」タイプの取引の1つです。どうぞ、お待ちしております。
最近のブロックには、SproutCore、JavaScriptMVC、Spine、Sammy、KnockoutなどのJavaScriptフレームワークがたくさんあります。しかし、いくつかの異なる理由から、この特定のプロジェクトではBackbone.jsが好きでした。
1.軽い(実際には100%無脂肪)
- 重量で、最新のパックバージョンは約4.6kbです
- コードでは、1,000行をわずかに超えるコードであるため、スタックトレースを追跡して、気を失うことなく内部を追跡することはそれほど難しくありません。
2.JavaScriptのように見えます
- JavaScriptなので、それだけです。
- それはあなたのおばあちゃんでさえ最近知っているjQueryを使用しています
3.超シンプルな永続性
- 箱から出して、データをバックエンドに(REST経由で)保持しますが、単一のプラグインをドロップすることで、代わりにローカルストレージに保存します
- 永続性APIを抽象化するため、ローカルストレージプラグインを削除するだけで、RESTバックエンドに永続化させることができます。
それでは始めましょう
Backbone.jsは単なるJavaScriptであるため、必要なのは、ページにUnderscore.jsと一緒に含めることだけです。 jQueryは、Backbone自体の強い依存関係ではありませんが、これを使用するので、ここに含めます。バックエンドの設定に煩わされたくないので、ローカルストレージプラグインもリンクします。簡単にするために、ここではファイルを直接リンクしていることに注意してください。ただし、本番環境では常に独自のアセットをホストする必要があります。
スクリプトsrc = "http://ajax.googleapis.com/ajax/libs/jquery/1.6.1/jquery.min.js"> / script> script src = "http://documentcloud.github.com/backbone/バックボーン-min.js "> / script> script src =" http://documentcloud.github.com/underscore/underscore-min.js "> / script> script src =" https://raw.github.com/ jeromegn / Backbone.localStorage / master / backbone.localStorage-min.js "> / script>
この記事の以下のコードはすべてアプリケーションに固有のものであるため、app.jsファイルに含めるか、それが必要な場合はインラインで含めることができます。バックボーンの後に含めることを忘れないでください。バックボーンを使用すると、アプリケーションの一部を抽象化して、再利用しやすいようにモジュール化し、他の人が読みやすくすることができます。その抽象化を最もよく説明するために、モデルから始めてビューで終わるFlickrBombの設計を下から上に説明しようとしていました。
私たちの最初のモデル
最初に取り組むべきタスクは、Flickrから写真を取得することです。バックボーンでのFlickrImageのモデリングは非常に簡単です。FlickrImageという新しいモデルを作成し、さまざまなサイズの親指を取得するのに役立ついくつかのメソッドを追加します。
var FlickrImage = Backbone.Model.extend({fullsize_url:function(){return this.image_url( 'medium');}、thumb_url:function(){return this.image_url( 'square');}、image_url:function( size){var size_code; switch(size){case'square ':size_code =' _ s '; break; // 75x75 case'medium':size_code = '_ z'; break; //最長側の640case'large ':size_code =' _ b '; break; //最長側の1024デフォルト:size_code =' ';} return "http:// farm" + this.get(' farm ')+ ".static.flickr.com / "+ this.get( 'server')+" / "+ this.get( 'id')+" _ "+ this.get( 'secret')+ size_code +" .webp ";}})
バックボーンのモデルは、他のMVCフレームワークのモデルと同様に、永続化できるオブジェクトであり、いくつかの関数が関連付けられています。バックボーンモデルの魔法の部分は、イベントを属性にバインドできることです。そのため、その属性が変更されたときに、それを反映するようにビューを更新できます。しかし、私たちは自分たちより少し進んでいます。
Flickrから写真を取得すると、すべてのサイズのURLを作成するのに十分な情報が得られます。ただし、そのアセンブリは私たちに任されているため、サイズパラメータを受け取り、パブリックリンクを返す.image_url()関数を実装しました。これはバックボーンモデルであるため、this.get()を使用してモデルの属性にアクセスできます。したがって、このモデルでは、コードの他の場所で次のことを実行して、Flickr画像のURLを取得できます。
flickrImage.image_url( ’large’)
かなり簡潔ですよね?このモデルはアプリケーションに固有であるため、フルサイズと親指の画像サイズのラッパー関数をいくつか追加します。
画像のコレクション
FlickrBombは単一の画像ではなく画像のコレクションを扱い、Backboneにはこれをモデル化するための便利な方法があります。適切な名前のコレクションは、Flickr画像を1つのプレースホルダーにグループ化するために使用するものです。
var FlickrImages = Backbone.Collection.extend({モデル:FlickrImage、キー:flickrbombAPIkey、ページ:1、フェッチ:関数(キーワード、成功){var self = this;成功=成功|| $ .noop; this.keywords =キーワード|| this.keywords; $ .ajax({url: 'http://api.flickr.com/services/rest/'、data:{api_key:self.key、format:' json '、method:' flickr。 photos.search '、tags:this.keywords、per_page:9、page:this.page、license:flickrbombLicenseTypes}、dataType:' jsonp '、jsonp:' jsoncallback '、success:function(response){self.add(response .photos.photo); success();}});}、nextPage:function(callback){this.page + = 1; this.remove(this.models); this.fetch(null、callback);}、 prevPage:function(callback){if(this.page> 1){this.page- = 1;} this.remove(this.models); this.fetch(null、callback);}});
ここで注意すべきことがいくつかあります。まず、 モデル 属性は、収集しているモデルのタイプをコレクションに通知します。後で使用するために初期化した属性もいくつかあります。keyはFlickrAPIキーであり、flickrbombAPIkeyを独自のFlickrAPIキーの文字列に置き換える必要があります。 Flickr APIキーの取得は無料で簡単です。次のリンクをたどってください:www.flickr.com/services/api/misc.api_keys.html。 page属性は、現在表示しているFlickr写真の現在のページです。
ここでの大きなメソッドは.fetch()です。これは、FlickrAPIから写真をプルする詳細を抽象化します。クロスドメインリクエストの問題を回避するために、FlickrAPIとjQueryの両方がサポートするJSONPを使用しています。 APIに渡す他のパラメーターは、一目瞭然です。ここで特に興味深いのは、バックボーン関数が呼び出されていることです。成功コールバックでは、.add()を使用しています。これは、モデル属性の配列を取得し、それらの属性からモデルインスタンスを作成して、それらをコレクションに追加する関数です。
.nextPage()関数と.prevPage()関数は、最初に表示するページを変更します。
コレクション関数.remove()を使用して、既存のすべてのモデルをから削除します。
コレクションを作成し、fetchを呼び出して、現在のページの写真を取得します(
かわった)。
FlickrBombImage
さかのぼって、プレースホルダー画像を表すもう1つのモデルが必要です。これは、FlickrImagesのコレクションと、選択されている現在のFlickrImageで構成されます。このモデルをFlickrBombImageと呼びます。
var localStorage =(supports_local_storage())? new Store( "flickrBombImages"):null; var FlickrBombImage = Backbone.Model.extend({localStorage:localStorage、initialize:function(){_。bindAll(this、 'loadFirstImage'); this.flickrImages = new FlickrImages(); this.flickrImages.fetch(this.get( 'keywords')、this.loadFirstImage); this.set(id:this.get( "id")); this.bind( 'change:src'、this.changeSrc) ;}、changeSrc:function(){this.save();}、loadFirstImage:function(){if(this.get( 'src')=== undefined){this.set({src:this.flickrImages。 first()。image_url()});}}});
このモデルは、ページの読み込み間で現在選択されている画像を追跡する役割を果たしているため、使用するローカルストレージストアを知る必要があります。最初の行は、localstorageがサポートされていることを確認してから、選択したイメージを永続化するために使用するストアを作成します。
バックボーンを使用すると、モデルのインスタンスが作成されたときに呼び出される.initialize()関数を定義できます。 FlickrBombImageでこの関数を使用して、FlickrImagesコレクションの新しいインスタンスを作成し、この画像に使用されるキーワードを渡してから、Flickrから画像をフェッチします。
.loadFirstImage()関数は、画像がFlickrから読み込まれたときに実行されるコールバックとして渡されました。ご想像のとおり、この関数は現在の画像をFlickrのコレクションの最初の画像に設定します。現在の画像がすでに設定されている場合は、これを行いません。
また、このモデルのsrc属性が変更されたときに、Backboneの属性コールバックを使用して.changeSrc()関数を起動します。このコールバックが行うのは、実装されているストアレイヤー(この場合はlocalstore)にモデルの属性を保持するバックボーンモデル関数である.save()を呼び出すことだけです。このように、選択した画像が変更されるたびに、それはすぐに保持されます。
ビューレイヤー
すべてのバックエンド(フロントエンドバックエンド)コードが記述されたので、ビューをまとめることができます。バックボーンのビューは、他の従来のMVCフレームワークのビューとは少し異なります。ビューは通常、プレゼンテーションにのみ関係しますが、バックボーンビューは動作にも責任があります。つまり、ビューは、何かがどのように見えるかだけでなく、操作されたときに何をすべきかを定義します。
ビューは通常(常にではありませんが)一部のデータに関連付けられており、そのデータからプレゼンテーションマークアップを生成するために3つのフェーズを経ます。
1. Viewオブジェクトが初期化され、空の要素が作成されます。
2.レンダリング関数が呼び出され、前の手順で作成した要素にビューを挿入して、ビューのマークアップを生成します。
3.要素がDOMにアタッチされます。
これは、マークアップを生成するための多くの作業のように思えるかもしれません。ビューの動作部分についてはまだ説明していませんが、重要です。その理由は次のとおりです。 DOMにある要素を変更するたびに、ブラウザーのリフローと呼ばれるものがトリガーされます。リフローは、ページ上のすべてのものがどのように配置されるかを再計算するブラウザです。ブラウザのリフローは、ドラッグまたはサイズ変更イベント内で呼び出された場合、パフォーマンスが低下する可能性があります。このイベントは非常に短い間隔で発生しますが、さらに悪いことに、見た目が悪くなります。複雑なページ操作を使用すると、実際にページに追加されている要素と、影響を受けた要素の再配置を確認できます。バックボーンの初期化、レンダリング、アタッチのパターンに従って、単一のリフローを保証し、要素操作の複雑さに関係なく、ページへの変更は知覚的に瞬時に行われます。
FlickrBombImageView
var FlickrBombImageView = Backbone.View.extend({tagName: "div"、className: "flickrbombContainer"、lock:false、template:_。template( 'div id = "%= this.image.id.replace(" "、 "")%> "... / div> ')、initialize:function(options){_。bindAll(this、' addImage '、' updateSrc '、' setDimentions '、' updateDimentions '); varキーワード=オプション。 img.attr( 'src')。replace( 'flickr://'、 ''); this。$ el = $(this.el); this.image = new FlickrBombImage({keywords:keywords、id:options。 img.attr( 'id')}); this.image.flickrImages.bind( 'add'、this.addImage); this.image.bind( 'change:src'、this.updateSrc);}、イベント:{ "click .setupIcon": "clickSetup"、 "click .flickrbombFlyout a.photo": "selectImage"、 "click .flickrbombFlyout a.next": "nextFlickrPhotos"、 "click .flickrbombFlyout a.prev": "prevFlickrPhotos"}、レンダリング:function(){$(this.el).html(this.template()); this.image.fetch(); this.resize(); return this;}、...});
このビューの機能は簡潔にするために省略されています。ソースコード全体はGitHubで入手できます:github.com/zurb/flickrbomb
ビューの上部には、バックボーン固有の属性がいくつかあります。 tagNameとclassNameは、このビューの要素に適用されるタグとクラスを定義するために使用されます。ビュー作成のステップ1はオブジェクトの作成であり、その作成はバックボーンによって処理されるため、要素とクラスを指定する必要があることに注意してください。バックボーンには適切なデフォルトがあることに注意してください。これらの属性を省略すると、デフォルトでdivが使用され、指定しない限りクラスは適用されません。
テンプレート属性は慣例ですが、必須ではありません。ここでは、このビューのマークアップを生成するために使用するJavaScriptテンプレート関数を指定するために使用しています。 Underscore.jsに含まれている_.template()関数を使用しますが、任意のテンプレートエンジンを使用できますが、判断することはありません。
.initialize()関数では、画像タグからキーワード文字列を引き出し、それらのキーワードを使用してFlickrBombImageモデルを作成しています。また、FlickrImageがFlickrImagesコレクションに追加されたときに実行される.addImage()関数をバインドしています。この関数は、新しく追加されたFlickrImageを画像セレクターフライアウトに追加します。最後の最も重要な行は、現在選択されているFlickrImageが変更されたときに起動するように.updateSrc()関数をバインドすることです。モデルで現在の画像が変更されると、この関数が実行され、画像要素のsrc属性が更新され、CSSは、ユーザーが指定した画像のサイズに収まるように画像のサイズを変更してトリミングします。
イベント:{"click .setupIcon": "clickSetup"、 "click .flickrbombFlyout a.photo": "selectImage"、 "click .flickrbombFlyout a.next": "nextFlickrPhotos"、 "click .flickrbombFlyout a.prev": "prevFlickrPhotos "}
.initialize()に続いて、ビューの動作部分があります。バックボーンは、イベントオブジェクトを使用してイベントをバインドする便利な方法を提供します。 eventsオブジェクトはjQuery.delegate()メソッドを使用してView要素への実際のバインドを実行するため、ビュー内の要素に対してどのような操作を行っても、バインドされたすべてのイベントは引き続き機能します。イベントをドキュメント全体にバインドする代わりに、任意の要素のスコープ内でイベントをバインドできることを除いて、jQuery .live()と同じように機能します。イベントオブジェクトの各エントリのキーは、イベントとセレクターで構成され、値は、そのイベントにバインドする必要がある関数を示します。 .delegate()は、submitなどの一部のイベントでは機能しないことに注意してください。サポートされているイベントの完全なリストについては、jQuery .live()のドキュメントを参照してください。
レンダリング:function(){$(this.el).html(this.template()); this.image.fetch(); this.resize();これを返す;}
最後に、マークアップを作成し、ViewマークアップがView要素に追加されるまで実行できない追加の作業を実行する.render()関数があります。テンプレートをレンダリングした後、FlickrBombImageで.fetch()を呼び出す必要があります。 .fetch()は、永続層からモデルの最新のコピーを取得するバックボーン関数です。以前にこのモデルを保存したことがある場合、.fetch()はそのデータを取得します。画像がフェッチされたら、サイズ変更を呼び出して画像を正しく配置する必要があります。
ホームストレッチ
すべてのピースが配置されたら、ページ上のプレースホルダー画像を見つけて、レンダリングされたFlickrBombImageビューに置き換えるだけです。
$( "img [src ^ = 'flickr://']")。each(function(){var img = $(this)、flickrBombImageView = new FlickrBombImageView({img:img}); img.replaceWith(flickrBombImageView。 render()。el);});
この小さな切り取りは、ページの下部で実行するか、ドキュメントの準備ができたコールバックで実行して、置き換えるプレースホルダー画像を確実に見つける必要があります。画像タグのsrc属性でflickr:// [KEYWORD]を指定する規則を使用して、Flickrからの画像を入力する必要があることを示します。 src属性が一致する画像要素を見つけ、新しいFlickrBombImageViewを作成してから、画像を私たちのものに置き換えます。元の画像のコピーを取得してFlickrBombViewに渡すと、要素で指定されている可能性のあるいくつかの追加の構成オプションを取得できます。
そのすべてのハードワークの最終結果は、ライブラリを使用する人々のための非常にシンプルなAPIです。彼らは、flickr://規則を使用して画像タグを定義し、ページの下部にFlickrBombコードをドロップするだけで、Flickrからプレースホルダー画像を取得できます。
大きな古いウェブアプリでもうまく機能します
クライアント側でコンテンツを生成することを気にせずに作成された、Notableと呼ばれる大きな古いWebアプリがあります。コンテンツクライアント側を生成することでアプリのセクションをターボチャージしたい場合は、バックボーンを選択しました。理由は同じでした。コードを整理するのに役立つ軽量のフレームワークが必要でしたが、アプリケーション全体を再考する必要はありませんでした。
私たちは今年初めに大きな成功を収めて変更を開始し、それ以来Backbonesの称賛を歌っています。
追加のリソース
バックボーンには、この記事で取り上げたものよりもはるかに多くのものがあります。スターター用のMVC(モデルビューコントローラー)のC(コントローラー)部分であり、実際には最新バージョンではR(ルーター)です。そして、それはすべてバックボーンのドキュメントでカバーされています。土曜日の朝の軽い読み物です。
documentcloud.github.com/backbone/
より伝統的なチュートリアルが必要な場合は、Backboneで記述されたこのtodoアプリケーションの非常によく文書化されたコードを確認してください。
documentcloud.github.com/backbone/docs/todos.html