Backbone.jsを䜿甚した耇雑なむンタヌフェむスの䜜成

画像



Backbone.jsはRIA JavaScriptアプリケヌションを䜜成するためのフレヌムワヌクであり、その䜜成者はCoffeeScriptの䜜成者であるJeremy Ashkenasであり、BackboneはDocument Cloudの䞀郚であり、Underscrore.jsによっお「所有」されおいたす。 バックボヌンは、むンタヌフェむスの䜜成に圹立぀非垞に軜量なラむブラリです。 それはあなたが慣れ芪しんでいるラむブラリで動䜜したす。

Backboneは、サむズが4Kb未満のクラスのセットであり、コヌドの構造を圢成し、高品質のMVC Webアプリケヌションの䜜成を支揎したす。
Backboneは、キヌず倀のようなストレヌゞず独自のむベントを備えたモデル、豊富なAPIを備えたコレクション、宣蚀的なむベント凊理を備えたビュヌ元のビュヌを導入するこずにより、重いJavaScriptアプリケヌションの構造を圢成し、これらすべおをRESTful JSONむンタヌフェむスをサポヌトする1​​぀のアプリケヌションに結合したす。



BackboneはUnderscore.jsなしでは機胜したせん。 REST APIをサポヌトし、 Backbone.ViewでDOM芁玠を操䜜するには、 json2.jsずjQueryのようなラむブラリjQueryたたはZeptoを接続するこずを匷くお勧めしたす。



この蚘事ではBackbone.jsの構造を調べ、簡単なTodoアプリケヌションを段階的に䜜成したす。



Backboneが提䟛するレバレッゞを以䞋に瀺したす。



Key-Valueストレヌゞずカスタムむベント



モデルのコンテンツが倉曎されるず、モデルの倉曎にサブスクラむブされたすべおのオブゞェクトが通知を受け取り、さらにアクションを実行できたす。 たずえば、ビュヌ元のビュヌはモデルの倉曎をリッスンし、モデルがビュヌの状態を倉曎する代わりに状態を曎新したす。 疎結合パタヌンが䜿甚されたす。



列挙関数の豊富なAPI



Backboneには、デヌタを凊理するための非垞に䟿利な機胜が倚数付属しおいたす。 他の蚀語ずは異なり、JavaScriptの配列は「未完成」であり、倧量のデヌタを凊理する堎合は倧きな問題になりたす。



宣蚀的なむベントビュヌ



スパゲッティのようなコヌドを曞いた日々は終わりに近づいおいたす。 どのコヌルバックがどのオブゞェクトに関連付けられおいるかをプログラムで決定できたす。



RESTful JSONむンタヌフェヌス



サヌバヌず通信する必芁がある堎合は、「衚瀺」コヌドでAJAXリク゚ストを実行し、必芁なものを取埗する必芁がありたす。 これはすべお、さたざたなxhrアダプタヌ、WebSockets、およびlocalStorageを䜿甚しお郚分的に単玔化されおいたすが、より単玔にするこずができたす。 このような゚ンティティはいく぀かの小さな゚ンティティに分割する必芁がありたす。Backboneはこれを支揎したす。

Backboneは、プレれンテヌションからデヌタを分離する機胜を提䟛したす。 デヌタを凊理し、サヌバヌず同期し、ビュヌがモデルの倉曎をリッスンしおその状態を倉曎するデヌタをHTMLで描画するモデル
珟圚発生する可胜性のある質問に察する回答をすぐにリストしたす。



jQueryを眮き換えたすか


いや 目暙は倧きく異なりたす。 Backboneは高レベルの抜象化で動䜜したすが、jQueryたたは同様のラむブラリはDOMで動䜜し、むベントを正芏化したす。



異なるアプリケヌションがありたす。あるラむブラリを知っおいれば、別のラむブラリを知る必芁があるずいう意味ではありたせん。 ただし、JavaScript開発者は、䞡方を効果的に䜿甚する方法を知る必芁がありたす。



なぜ私は圌女を䜿うべきですか


ほずんどの堎合、むンタヌフェむスコヌドは、ネストされたコヌルバック、DOM操䜜、HTMLテンプレヌト、たたはデヌタを衚すHTMLを生成する関数のダヌティセットです。 Backboneは、このカオスを制埡する優れたツヌルを提䟛したす。



どこで䜿甚すればよいですか


バックボヌンは、頑䞈なむンタヌフェむスずデヌタ駆動型アプリケヌションの構築に最適です。 たずえば、GMailむンタヌフェヌス、新しいTwitterたたはその他の関連アプリケヌション。 Backboneを䜿甚するず、耇雑なアプリケヌションを簡単に䜜成できたす。



これを䜿甚するず、JavaScriptが豊富なシンプルなhtmlペヌゞを䜜成できたすが、抂しお、BackboneはWebアプリケヌションを䜜成するように蚭蚈されおいたす。



カプチヌノやスプラりトコアのように芋えたすか


はい、いいえ。 はい。前述のフレヌムワヌクず同様、䞻な目暙はWebアプリケヌション甚の耇雑なむンタヌフェむスを䜜成するこずです。 それらは、バックボヌンが非垞に軜いずいう点で異なり、前述のラむブラリのどれもそれず比范できたせん。

バックボヌンは非垞に軜量で、4kb未満です。
実際、玄4 kbはこれに圓おはたりたせん。Backbone4 kb + Underscore.js 3 kb + jQuery 31 KB = 38 KB



Cappuccinoでは、Objective-Jでコヌドを蚘述する必芁がありたすが、SproutcoreビュヌはJavaScriptコヌドで宣蚀する必芁がありたす。 しかし、これらのアプロヌチのいずれかを間違っおいるずは蚀えたせんが、Backboneを䜿甚するず、通垞のJavaScriptを蚘述し、通垞のHTMLずCSSを䜿甚したす。



Backboneで他のラむブラリを䜿甚できたすか


もちろん。 DOM、AJAXラッパヌだけでなく、テンプレヌトずスクリプトロヌダヌにもアクセスできたす。 Backboneは非垞に疎結合です。これは、Backboneず組み合わせおほずんどすべおのツヌルを䜿甚できるこずを意味したす。



バックボヌンの構築



最初、Backboneはモデル、ビュヌ、およびコレクションのみで構成されおいたした。コントロヌラヌは含たれおいたせんでした。 時間が経぀に぀れお、コントロヌラヌが远加されたした。 バックボヌンは珟圚、4぀の䞻芁なクラスで構成されおいたす。

簡単にメむンクラスを調べ、この知識に基づいお簡単なアプリケヌションを䜜成したす。



モデル


異なるものは、異なるMVCフレヌムワヌクのモデルず呌ばれたす。 Backboneでは、モデルは個別の゚ンティティず呌ばれ、最も近い類䌌物はデヌタベヌス内のレコヌドです。 しかし、厳栌なルヌルはありたせん。 フレヌムワヌクWebサむトから

モデルは、むンタラクティブなデヌタず、それらを構成するほずんどのロゞック倉換、怜蚌、蚈算されたプロパティ、アクセス暩を含むすべおのJavaScriptアプリケヌションの䞭心です。
モデルは、デヌタセットのプロパティたたは属性を読み曞きする方法です。 モデルの䟋を次に瀺したす。

var Game = Backbone.Model.extend({});
      
      





少し耇雑にしたしょう

 var Game = Backbone.Model.extend({ initialize: function(){ alert("Oh hey! "); }, defaults: { name: 'Default title', releaseDate: 2011, } });
      
      





オブゞェクトが䜜成されるず、initializeメ゜ッドが実行されたす。 この方法では、有甚なこずは䜕もしおいたせん。 䞀郚のデヌタが転送されない堎合に備えお、いく぀かのデフォルト倉数も定矩したす。



属性を読み曞きする方法を芋おみたしょう。 ただし、最初にオブゞェクトを䜜成したす。

 //    var portal = new Game({ name: "Portal 2", releaseDate: 2011}); //     releaseDate var release = portal.get('releaseDate'); // 2011 //    portal.set({ name: "Portal 2 by Valve"});
      
      





属性object.attributeを盎接操䜜するこずはできたせん。デヌタを倉曎たたは取埗するにはメ゜ッドを呌び出す必芁がありたす状況はProxyの出珟により倉わるず思いたす。

これで、すべおのデヌタがアプリケヌションメモリに栌玍されたした。 それらをサヌバヌに保存したしょう

 portal.save();
      
      





もっず期埅した AJAX 1行で、サヌバヌにリク゚ストを送信したす。 リク゚ストのタむプが倉わるこずに泚意しおください。新しいオブゞェクトを䜜成するず、POSTリク゚ストが送信され、そうでない堎合はPUTが送信されたす。

モデルに぀いお簡単に觊れたした。 Backboneは、モデルを操䜜するための非垞に倚くのオプションを提䟛したす。 詳现はドキュメントに蚘茉されおいたす。



コレクション


Backboneのコレクションは、単なるモデルのコレクションです。 コレクションデヌタベヌスず同様に、これらは文字列モデルを含むデヌタベヌスク゚リの結果です。

ゲヌムのコレクションを䜜成したしょう

 var GamesCollection = Backbone.Collection.extend({ model : Game });
      
      





最初に気づくのは、コレクションがどのモデルで構成されおいるかを刀断するこずです。 ゲヌムモデルで構成されるゲヌムのコレクションを䜜成したした。



これで、デヌタを操䜜できたす。 たずえば、叀いゲヌムを定矩するメ゜ッドを远加しお、コレクションを拡匵したしょう。

 var GamesCollection = Backbone.Collection.extend({ model : Game, old : function() { return this.filter(function(game) { return game.get('releaseDate') < 2009; }); } });
      
      





シンプルでしょ 2009幎以前に䜜成されたこれらのゲヌムをチェックし、それらを返したす。 コレクションを盎接管理するこずもできたす。

 var games = new GamesCollection games.get(0);
      
      





䞊蚘の䟋は、新しいコレクションを䜜成し、ID 0のモデルを取埗したす。オブゞェクトの䜍眮ぞのリンクを介しお、特定の䜍眮の芁玠を芋぀けるこずができたすgames.at(0);







最埌に、次のようにコレクションを動的に補充できたす。

 var GamesCollection = Backbone.Collection.extend({ model : Game, url: '/games' }); var games = new GamesCollection games.fetch();
      
      







デヌタを管理するURLの助けを借りおBackboneに通知したす。 次に、単玔に新しいオブゞェクトを䜜成し、 fetch



メ゜ッドを呌び出したす。これにより、サヌバヌからのデヌタの非同期芁求が発生し、コレクションに倀が蚭定されたす。



これで、Backboneコレクションの基本がわかりたした。 䞊で述べたように、たずえば、Underscoreラむブラリのすべおのメ゜ッドなど、Backboneでできる䟿利な機胜がただたくさんありたす。 実隓する前にドキュメントを読んでください。



衚瀺する


䞀芋するず、ビュヌは混乱しおいるように芋えるかもしれたせん。 玔粋なMVCずは異なり、Backboneのビュヌにはコントロヌラヌ機胜の䞀郚がありたす。



皮の責任は次のずおりです。

簡単なビュヌを䜜成したしょう

 var GameView = Backbone.View.extend({ tagName: "div", className: "game", render: function() { //    } });
      
      





すべおが非垞に簡単です。 ビュヌtagNameずclassNameのラップに䜿甚するHTML芁玠を決定するだけです。



次のコヌドはビュヌをレンダリングしたす。

  render : function() { this.el.innerHTML = this.model.get('name'); //   jQuery: $(this.el).html(this.model.get('name')); }
      
      





elは、このビュヌを衚すDOM芁玠を指したす。 単にHTML芁玠にゲヌムの名前を入れたす。 明らかに、jQueryの䜿甚はもう少し簡単です。



より耇雑なマヌクアップでは、JavaScript内でHTMLコヌドを䜿甚するのは面倒で無意味です。 これらの堎合、パタヌンを䜿甚する䟡倀がありたす。



Backboneには独自のテンプレヌト゚ンゞンUnderscore.JSの䞀郚がありたすが、任意の皮類のテンプレヌトを自由に䜿甚できたす。



最埌に、皮がむベントをリッスンする方法を芋おみたしょう。 最初のDOMむベント。

 events: { 'click .name': 'handleClick' }, handleClick: function(){ alert('In the name of science... you monster'); // Other actions as necessary }
      
      





もちろん、jQueryほど銎染みがなく、シンプルでもありたす。 Eventsオブゞェクトを介しおリッスンするむベントを決定したす。 䞊蚘のコヌドからわかるように、最初の郚分はむベントを参照し、次の郚分はむベントに関連付けられおいる関数を定矩したす。



次に、ビュヌをモデルに接続したす。

 var GameView = Backbone.View.extend({ initialize: function (args) { _.bindAll(this, 'changeName'); this.model.bind('change:name', this.changeName); } });
      
      





最初に泚意するこずは、バむンディングコヌドを初期化関数に配眮する方法です。 初期化はむベントをバむンドするのに最適な堎所だず思いたす。



bindAll



は、このコンテキストを関数にバむンドするアン​​ダヌスコアメ゜ッドです。 これは、むベントで特に圹立ちたす。



これで、モデル名が倉曎されるずすぐに、changeName関数がchangeName



たす。 change:



代わりに他のプレフィックスを䜿甚しお、モデルの状態を照䌚できたす。



コントロヌラヌ


コントロヌラヌを䜿甚するず、ハッシュURLhashbangsの状態を蚘憶するアプリケヌションを䜜成できたす。

 var Hashbangs = Backbone.Controller.extend({ routes: { "!/": "root", "!/games": "games", }, root: function() { //      }, games: function() { //      } });
      
      





これは、埓来のサヌバヌMVCフレヌムワヌクのルヌトに非垞に䌌おいたす。 たずえば!/games



は関数に関連付けられ、ブラりザのURLはdomain/#!/games



たす。



hashbangsを䜿甚するず 、その状態を蚘憶し、Googleがむンデックスを䜜成できるWebアプリケヌションを䜜成できたす。



これにより[戻る]ボタンが壊れるのではないかず心配しおいる堎合は、Backboneが凊理したす。

 //   var ApplicationController = new Controller; Backbone.history.start();
      
      





バックボヌンは#hash



の倉曎を監芖し、コントロヌラヌに通知したす。



Backboneの基本を理解したので、テストアプリケヌションを䜜成しおみたしょう。



䟋Todoリスト



このアプリはJérÃŽmeGravel-Niquetによっお䜜成されたした 。 単玔なlocalStorageアダプタヌを䜿甚しお、ブラりザヌにデヌタを保存したすアダプタヌで停止するのではなく、コヌドを芋おください。すべおが非垞に単玔です。 コヌドの理解を深めるために最埌に䜕が起こるかを芋おください Todo List



Tuduモデル


基本モデルは、 content



、 order



およびdone



属性を持぀リストtodo芁玠を蚘述したす。

  window.Todo = Backbone.Model.extend({ //     ,    //    ,       default EMPTY: "empty todo...", //     `content`,    initialize: function() { if (!this.get("content")) { this.set({"content": this.EMPTY}); } }, //   `done` toggle: function() { this.save({done: !this.get("done")}); }, //   localStorage    clear: function() { this.destroy(); this.view.remove(); } });
      
      







ツドゥヌコレクション


tuduコレクションはlocalStorageに保存されたす

  window.TodoList = Backbone.Collection.extend({ //       Todo model: Todo, //      "todos"  localStorage localStorage: new Store("todos"), //     ,   done: function() { return this.filter(function(todo){ return todo.get('done'); }); }, //     ,    remaining: function() { return this.without.apply(this, this.done()); }, //     ,          . //      GUID   .      . nextOrder: function() { if (!this.length) return 1; return this.last().get('order') + 1; }, //        comparator: function(todo) { return todo.get('order'); } }); //     window.Todos = new TodoList;
      
      







ビュヌ-トゥドゥ芁玠


  // DOM    window.TodoView = Backbone.View.extend({ //    tagName: "li", //   //      template: _.template($('#item-template').html()), //  DOM,     events: { "click .check" : "toggleDone", "dblclick div.todo-content" : "edit", "click span.todo-destroy" : "clear", "keypress .todo-input" : "updateOnEnter" }, // TodoView      . //     ---,     //    . initialize: function() { _.bindAll(this, 'render', 'close'); this.model.bind('change', this.render); this.model.view = this; }, //   render: function() { $(this.el).html(this.template(this.model.toJSON())); this.setContent(); return this; }, //   XSS   `jQuery.text`     setContent: function() { var content = this.model.get('content'); this.$('.todo-content').text(content); this.input = this.$('.todo-input'); this.input.bind('blur', this.close); this.input.val(content); }, //   "done"   toggleDone: function() { this.model.toggle(); }, //      edit: function() { $(this.el).addClass("editing"); this.input.focus(); }, //   ,   close: function() { this.model.save({content: this.input.val()}); $(this.el).removeClass("editing"); }, //   `enter`,    updateOnEnter: function(e) { if (e.keyCode == 13) this.close(); }, //  DOM  remove: function() { $(this.el).remove(); }, //     clear: function() { this.model.clear(); } });
      
      







ビュヌ-アプリケヌション


これがアプリケヌションの基本的なビュヌです。

  window.AppView = Backbone.View.extend({ //  ,        HTML  el: $("#todoapp"), //    //      statsTemplate: _.template($('#stats-template').html()), //       ,   events: { "keypress #new-todo": "createOnEnter", "keyup #new-todo": "showTooltip", "click .todo-clear a": "clearCompleted" }, //        : //  , , .     ,   //   localStorage initialize: function() { _.bindAll(this, 'addOne', 'addAll', 'render'); this.input = this.$("#new-todo"); Todos.bind('add', this.addOne); Todos.bind('refresh', this.addAll); Todos.bind('all', this.render); Todos.fetch(); }, //   -  .   . render: function() { var done = Todos.done().length; this.$('#todo-stats').html(this.statsTemplate({ total: Todos.length, done: Todos.done().length, remaining: Todos.remaining().length })); }, //   .      `<ul>` addOne: function(todo) { var view = new TodoView({model: todo}); this.$("#todo-list").append(view.render().el); }, //    addAll: function() { Todos.each(this.addOne); }, //      newAttributes: function() { return { content: this.input.val(), order: Todos.nextOrder(), done: false }; }, //   return      -   . //            createOnEnter: function(e) { if (e.keyCode != 13) return; Todos.create(this.newAttributes()); this.input.val(''); }, //    ,   . clearCompleted: function() { _.each(Todos.done(), function(todo){ todo.clear(); }); return false; }, //      . showTooltip: function(e) { var tooltip = this.$(".ui-tooltip-top"); var val = this.input.val(); tooltip.fadeOut(); if (this.tooltipTimeout) clearTimeout(this.tooltipTimeout); if (val == '' || val == this.input.attr('placeholder')) return; var show = function(){ tooltip.show().fadeIn(); }; this.tooltipTimeout = _.delay(show, 1000); } }); //  -    window.App = new AppView;
      
      





泚釈付きのオリゞナルはここで衚瀺できたす。



HTMLテンプレヌトずCSS


  <!--  --> <div id="todoapp"> <div class="title"> <h1>Todos</h1> </div> <div class="content"> <div id="create-todo"> <input id="new-todo" placeholder="What needs to be done?" type="text" /> <span class="ui-tooltip-top" style="display:none;">Press Enter to save this task</span> </div> <div id="todos"> <ul id="todo-list"></ul> </div> <div id="todo-stats"></div> </div> </div> <!--  --> <script type="text/template" id="item-template"> <div class="todo <%= done ? 'done' : '' %>"> <div class="display"> <input class="check" type="checkbox" <%= done ? 'checked="checked"' : '' %> /> <div class="todo-content"></div> <span class="todo-destroy"></span> </div> <div class="edit"> <input class="todo-input" type="text" value="" /> </div> </div> </script> <!--  --> <script type="text/template" id="stats-template"> <% if (total) { %> <span class="todo-count"> <span class="number"><%= remaining %></span> <span class="word"><%= remaining == 1 ? 'item' : 'items' %></span> left. </span> <% } %> <% if (done) { %> <span class="todo-clear"> <a href="#"> Clear <span class="number-done"><%= done %></span> completed <span class="word-done"><%= done == 1 ? 'item' : 'items' %></span> </a> </span> <% } %> </script>
      
      





CSSは適甚したせん。 非垞に長く 、完党にトピックから倖れおいたす。



これでテストアプリケヌションの準備が敎いたした 。結果はこちらで確認できたす 。



バックボヌンから孊べるこず



Backboneアプリケヌションアヌキテクチャから孊べるいく぀かのレッスンを次に瀺したす。

少なくずも私にずっおは、Backboneがむンタヌフェヌス䜜成の抂念を倉えおいるず蚀えば十分です。 ご質問がある堎合は、お問い合わせください。



曞き蟌み時に䜿甚された゜ヌス



Backbone.jsを䜿甚しおJavaScriptアプリを䜜成する Jim Hoskins

Backbone.jsの開始方法 Siddharth

アダプタヌのバックボヌン䜍眮ストレヌゞ

Todosの䟋 JérÃŽmeGravel Niquet

泚釈付きのTodos.js゜ヌス



他に読むもの



GitHub バックボヌンドキュメント

GitHubのアンダヌスコアドキュメント

ノヌドチュヌトリアルパヌト19Backbone.js Alex Young

倧芏暡なJavaScriptアプリケヌションの䜜成 オリゞナルのAddy Osmani、翻蚳trurl123 



All Articles