1

Backbone.jsを使用してシングルページアプリに取り組んでいます。私に発生した問題は、ページをリロードしていないため、ビューのインスタンスを作成するときに、ビューオブジェクトがアプリの存続期間中メモリに残っていると想定することです。別のルートが呼び出された場合、特定のビューが不要になる可能性があるため、これは私にはあまり効率的ではないようです。ただし、特定のビューが元のルートに戻った場合は、後で「表示」する必要がある場合があります。したがって、問題は、ルートに関してBackboneでビューを最適に管理する方法です。

私のアプリでは、ビューの多くが特定の「ページ」の表示を担当しているため、同じDOM要素を共有しています。これらの「ページ」ビューの1つが呼び出されると、以前に配置されたDOM要素のコンテンツが前のビューに置き換えられます。したがって、前のビューは不要になります。

以前のビューを手動で破棄する必要がありますか(または、これは何らかの方法でルーターオブジェクトによって処理されますか)?または、初期化されたビューをそのままにしておく方がよいでしょうか。

次のサンプルコードは、アプリのルーターでビューインスタンスがどのように作成されているかを示しています。

/** 
 * View - List of contacts 
 */    
var ListContactsView = Backbone.View.extend({
  el: '#content',
  template: _.template($('#list-contacts-tpl').html()),
  initialize: function() {
    _.bindAll(this, 'render');
    this.collection = new Contacts();
    this.collection.bind('reset', this.render);
    this.collection.fetch();
  },
  render: function() {
    this.$el.hide();
    this.$el.html(this.template({ contacts: this.collection }));
    this.$el.fadeIn(500);
  }
});

/** 
 * View - Display single contact 
 */
var DisplayContactView = Backbone.View.extend({
  el: '#content',
  events: {
    'click #delete-contact-button': 'deleteContact'
  },
  template: _.template($('#display-contact-tpl').html()),
  initialize: function() {
    _.bindAll(this, 'deleteContact', 'render');
    // Create reference to event aggregator object.
    if (typeof this.options.id === 'undefined') {
      throw new Error('View DisplayContactView initialized without _id parameter.');
    }
    this.model = new Contact({ _id: this.options.id });
    // Add parse method since parsing is not done by collection in this 
    // instance, as this model is not called in the scope of collection 
    // Contacts.
    this.model.parse = function(response) {
      return response.data;
    };
    this.model.bind('change', this.render);
    this.model.fetch();
  },
  deleteContact: function(id) {
    // Trigger deleteContact event.
    this.eventAggregator.trigger('deleteContact', id);
  },
  render: function() {
    this.$el.html(this.template({ contact: this.model.attributes }));
  }
});

/**
 * Page routes
 */
var $content = $('#content');
var ClientSideRouter = Backbone.Router.extend({
  routes: {
    'browse': 'browse',
    'browse/view/:id': 'browseViewContact',
    'orgs': 'orgs',
    'orgs/:orgName': 'orgs',
    'orgs/:orgName/:id': 'orgs',
    'contact/add': 'addContact',
    'contact/view/:id': 'viewContact',
    'contact/delete/:id': 'confirmDelete',
    '*path': 'defaultPage'
  },
  addContact: function() {
    // Display contact edit form.
    var editContactFormView = new EditContactFormView();
    // Display email field in edit form.
  },
  browse: function() {
    var listContactsView = new ListContactsView();
  },
  browseViewContact: function(id) {
    var displayContactView = new DisplayContactView({ id: id });
  },
  defaultPage: function(path) {
    $content.html('Default');
  },
  home: function() {
    $content.html('Home');
  },
  viewContact: function(id) {
    $.ajax({
      url: '/contact/view/' + id,
      dataType: 'html',
      success: function(data) {
        $content.html(data);
      }
    });
  }
});

var clientSideRouter = new ClientSideRouter();
Backbone.history.start();
4

2 に答える 2

2
  • ルートはビューを破壊しません

ルートは、URLの変更を操作するための便利な方法を提供します。便宜上、私は現在のページのURLセマンティクスとコンテキストを意味します。たとえば、url#/!/create/は、モデルを作成するためのフォームを表示する必要があるメソッドを呼び出します。ここでのコンテキストは、モデルを作成するためのビューです。

  • ビューは開発者が管理する必要があります

Backbone.jsでビューを管理するためのよく知られた方法はまだ存在しませんが、私はグローバル変数の方法を好みます。これにより、ビューインスタンスがアプリケーション全体で利用可能になり、すべてのモジュールがそれらにアクセスできるようになります。たとえば、これを行う

window.App.Contacts.ContactView = new App.Contacts.View.ContactView({model:BenContact}); ベンの連絡先情報を表示するために使用されるビューを、ウィンドウオブジェクトを介してアプリケーションモジュールで利用できるようにします。同じものを使用するビューに対して行う必要があるelのは、を破棄しContactViewて新しいビューをレンダリングすることだけです。

  • それらを削除するためのメソッドが表示されています

イベントの委任解除および削除メソッドは、それらを削除するのに役立ちます。ルートハッシュ変更イベントを処理するコールバックメソッドの内部。たとえば、#/!/view/all(すべての連絡先リストを表示するためのURL)を処理するコールバックメソッドでは、両方のビューが同じものを使用する状況に遭遇する可能性があるelため、を破棄しContactViewてレンダリングする必要ListViewがあるため、コールバックでこれを実行します

App.Contacts.ContactView.undelegateEvents();

App.Contacts.ContactView.remove();

于 2012-06-04T05:20:59.403 に答える
1

Backbone.jsにはビュー構成のサポートが組み込まれていないため、子ビューを追跡する場合に従うことができるパターンがいくつかあります。

  • Derick Baileyは、Backbone.Viewを拡張して、ビューを後でクリーンアップできるようにする方法を示しています -http://lostechies.com/derickbailey/2011/09/15/zombies-run-managing-page-transitions-in-backbone-apps/

  • もう1つの方法は、親ビューのプロパティに子ビューを追加し、親ビューの状態が削除されたときに手動でクリーンアップすることです。

    var ParentView = Backbone.View.extend({initialize:function(){this.childViews = [];}、render:function(){this.childViews.push(new ChildView);}});

  • 3番目の方法は、親ビューがトリガーするイベントを子ビューにサブスクライブさせて、親ビューが「閉じる」イベントを公開したときにクリーンアップできるようにすることです。

また、コードから、子ビュークラス内で実際にモデルをフェッチしていることに気付きました。理想的には、モデルをパラメーターとしてコンストラクターに渡すことをお勧めします。これにより、ビューがデータから切り離されます。それはもっとMVCっぽいです

于 2012-06-04T05:28:18.627 に答える