バックボーンを使用したケーススタディ

この記事では、Backboneの使用、特にサーバーで動作するコードの例について説明します。 これは、シーカーの放浪の一種の中間点であるはずです。



この出版物が必要なのはなぜですか? このトピックに関する記事は既にありますが、パスはドキュメント化されていない状態で表示する必要がありますが、ドキュメントにすでに記載されているものに非常に表面的にしか影響しません。 まさにそのとおりです。バックボーンはJqueryのような複雑なスタンドアロンライブラリではありません。 このライブラリは、おおよその構造を構築することのみを目的としています。 このマテリアルから必要なものをスカルプトできます。 繰り返しますが、既製のパターンを探すことには意味がありません。文字ごとの例を再印刷する必要はありませんが、それでも役に立ちません。 このツールの使用方法を学習してから、バトルに突入する必要があります。



それで、あなたはhabrakatのラインを越えました。 ライブラリの基本原則の説明を目標として設定していません。すでに多くの記事がありました。

habrahabr.ru/blogs/javascript/129928

habrahabr.ru/blogs/javascript/118782

habrahabr.ru/blogs/webdev/123130



3つすべてがBackboneの標準的な使用について説明していることに注意してください。ただし、たとえばルーターを使用するなど、実際に必要になることはほとんどありません。 または、サーバーとの連絡をとる必要があります-しかし、それを行う方法は? すべてBackbone.syncを参照していますが、何らかの理由で誰も例を提供していません。 このメモを書く主な理由の1つとして、前の文を検討してください。 あなたが彼に同意しない場合、あなたはそれ以上読むことができません。



始めましょう。 フロントエンドの編集メモを作成します。 私たちはスクリプトに焦点を合わせ、ユーザーの審美的な望みと選択する権利の両方を大胆に無視しています:私はクロムでのみテストします。 最後にアーカイブの例とコードへのリンクを示します。



始めるには何が必要ですか? 標準構造で空のxhtmlページを作成し、jquery、アンダースコア、バックボーンを(この順序で)接続します。 最後に、スクリプトへのリンクを追加します。 サーバー側では、データの読み取り/書き込みを担当するphpファイルを作成します(app.phpアーカイブにあります。コードは提供しません。スクリプトは次の形式のリクエストを処理しますか?Method =)。



準備が完了したら、jsでスクリプトの作成を開始します。 モデルとログを保存するためのコンテナを作成しましょう:

app = { debug: true, log: function(obj) { if(this.debug) { console.log(obj); } }, models: {} }
      
      





Backbone.sync関数は、何も台無しにせずに再宣言するのが非常に簡単になるように設計されています。 さらに、各モデルには独自の同期メソッドがあります(それは何と呼ばれるべきでしょうか?)。 スクリプト全体のグローバル関数を作成します。 私たちが追求する目標:



私に起こったこと(あなたの実装は異なるかもしれません):

 Backbone.sync = function(method, model, options) { //     var method = (method=='update'||method=='create')?'save':method; //    if(model.loading && model.loading.method == method) { model.loading.xhr.abort(); } app.log('  "'+model.url(method)+'"'); var xhr = $.ajax({ type: 'POST', url: model.url(method), data: (model instanceof Backbone.Model)?model.toJSON():{}, success: function(ret) { //    if(ret.is_error) { app.log(' '); } else { app.log(' '); (function(data){ app.log('Backbone.sync  :', data); if(data.res) { //  - ,   model.trigger('load:res', data.res); } else { //  - ,   options.success(data.rows?data.rows:data); } model.trigger((method=='save')?'save':'load', data); })(ret.data); } }, error: function (req_obj, msg, error) { app.log(' '); }, dataType: 'json' }); //       model.loading = { method: method, xhr: xhr } };
      
      





私は少しずるいです。 次のようなモデルメソッドを呼び出す場合:read list readの場合、最後のreadは最初のreadを壊しませんが、記事はそれについてではないので、巨大なボルトを配置します。



モデルコードの記録:

 app.models.note = (Backbone.Model.extend({ defaults: { id: 0, text: '' }, url: function(method){ return './app.php?method='+method; } })); app.models.Note = (Backbone.View.extend({ tagName: 'li', className: 'entity', render: function(){ var data = this.model.toJSON(); var that = this; $(this.el).html('').data('rowId', data.id); $(this.el).append($('<input type="text" />').val(data.text)); $(this.el).append($('<button></button>').click(function(){ app.models.page.trigger('post:save', { 'id': $(this).closest('li').data('rowId'), 'text': $(this).closest('li').find('input').val() }); })); $(this.el).append($('<button></button>').click(function(){ if(!confirm(' ,     ?')) return; app.models.notes.get($(this).closest('li').data('rowId')).destroy(); })); return this; } }));
      
      





エントリーのリスト:

 app.models.notes = new (Backbone.Collection.extend({ model: app.models.note, initialize: function(){ this.bind('destroy', function(){ this.reload(); }, this); }, reload: function(){ var that = this; var options = ({ error:function(){ app.log('  !'); that.trigger('change'); }, success: function(){ app.log(' '); that.trigger('change'); } }); app.log(' ...'); this.fetch(options); }, url: function(method){ return './app.php?method=list'; } }));
      
      





最後に、ページモデル:

 app.models.page = new (Backbone.View.extend({ el: null, el_list: null, notes: null, initialize: function(){ this.bind('page:load', this.pageLoad, this); this.bind('list:reload', this.listReload, this); this.bind('post:save', this.postSave, this); this.notes = app.models.notes; this.notes.bind('change', this.onListChange, this); this.notes.bind('load:res', this.onListChange, this); return this; }, pageLoad: function(data) { var that = this; this.el = $('.layout'); this.el_list = this.el.find('.items-list'); //   this.el.find('.title .refresh').bind('click', function(){ that.trigger('list:reload') }); //   this.el.find('.items-add-submit').bind('click', function(){ that.trigger('post:save', { id: false, text: $('.items-add-text').val() }); }); this.trigger('list:reload'); }, render: function(ret){ $(this.el_list).html(''); if(!ret) { app.log(' . : '+this.notes.length); _(this.notes.models).each(function(item){ this.appendItem(item); }, this); } else { app.log(' . : "'+ret+'"'); $(this.el_list).html('').append($('<li class="res"></li>').text(ret)); } return this; }, appendItem: function(item) { var view = new app.models.Note({ model: item }); $(this.el_list).append(view.render().el); }, onListChange: function(ret){ this.render(ret); }, postSave: function(obj){ var model = new app.models.note(); if(obj.id) { model.set({ id:obj.id }); } model.set({ text:obj.text }); model.save(); this.trigger('list:reload'); }, listReload: function(){ this.notes.reload(); } }));
      
      





彼らは何かを忘れました...ああ、そうです、我々はレンダリングを開始します:

 $(document).ready(function(){ app.models.page.trigger('page:load'); });
      
      







ご覧のとおり、すべてがシンプルです。 各関数を噛む代わりに、意図的にコードを分割して引用しました。 この記事は、js /バックボーンに少なくとも少し精通している人に焦点を当てています。 これがあなたに関するものではない場合は、上記のリンクを提供しました。すべてがそこで詳細に説明されています。 コードの理解が困難な場合、またはコードの追加説明が必要な場合は、記述してください。

アクションのコード: yurov.me/art

アーカイブ内のすべてのコード: yurov.me/art/art.tar.gz



サーバー上のPsコードはオークで、グリッチが発生する可能性があります。 フロントエンドを表示することが重要です。 動作しない場合は、ローカルで実行するか、単にアーカイブを参照してください。



PPS同志oWeRQはコードを整理しました。後で記事を更新します(コードはずっときれいです):

owerq.dyndns.org/test/art



All Articles