Делегирование событий для подвидов в Backbone.js - PullRequest
17 голосов
/ 22 декабря 2011

Мы все знаем, что делать что-то подобное плохо:

<ul>
  <li>Item</li>
  <li>Item</li>
  ... 500 more list items
</ul>

, а затем ...

$("ul li").bind("click", function() { ... });

Я просматривал множество примеров / руководств по Backbone, и следующее, кажется, является стандартным подходом к отображению списка с элементами на основе коллекции моделей.

var ListView = Backbone.View.extend() {

  tagName: 'ul',

  render: function() {
    this.collection.each(function(item) {
      var view = new ListItemView({model: item});
      $(this.el).append(view.render().el);
    });
    return this;
  }
});

Представление элемента списка:

var ListItemView = Backbone.View.extend() {

  tagName: 'li',

  events: {
   'click' : 'log'
  }

  log : function() {
    console.log(this.model.get("title"));
  }

  render: function() {
    $(this.el).html(this.template(this.model.toJSON()));
    return this;
  }
});

Если я не ошибаюсь, создание экземпляра listView с коллекцией из 500 моделей дает мне 500 событий нажатия, по одному для каждой строки. Это плохо, верно?

Я знаю, что Backbone встроил делегирование событий для событий в пространстве имен:

events : {
  'click li' : 'log'
}

Полагаю, я мог бы поместить это в свой ListView, и это создало бы только одно событие щелчка для всего списка, но тогда я не смог бы получить доступ к данным модели, соответствующим элементу списка, по которому щелкнули.

Какие шаблоны используют разработчики магистральных сетей для решения этой типичной проблемы?

Ответы [ 3 ]

9 голосов
/ 22 декабря 2011

Дерик Бэйли написал подробное сообщение в блоге об этой дилемме, вы можете проверить его здесь: http://lostechies.com/derickbailey/2011/10/11/backbone-js-getting-the-model-for-a-clicked-element/

2 голосов
/ 06 июля 2012

Отслеживать подпредставления из родительского представления. Затем при добавлении подпредставления добавьте его в хеш, а также добавьте cid в el подпредставления. Таким образом, есть указатель на подпредставление и может выполнять операции над его моделью и т. Д. *

Я не проверял этот точный код ниже, поэтому ЭТО может быть неверно в одном или двух местах, но я проверил этот общий принцип. Я также опустил код listitemview.

var ListView = Backbone.View.extend() {
  subViews: {},
  tagName: 'ul',
  events: {
    'click li' : 'clickItem'
  },
  clickItem: function(event){
     var id = event.currentTarget.cid;
     var subView = this.subViews[id];


  },
  render: function() {

    this.collection.each(function(item) {
      var view = new ListItemView({model: item});
      this.subViews[view.cid] = view;
      subEl = view.render().el;
      subEl.cid = view.cid;
      $(this.el).append(subEl);
    });
    return this;
  }
});
2 голосов
/ 22 декабря 2011

Вы можете связать экземпляр с таким элементом:

events : {
  'click li' : 'log'
},

log: function( e ) {
var elm = e.currentTarget //Same as `this` in normally bound jQuery event


jQuery.data( elm, "viewInstance" ).log( e );
},

Тогда:

var ListItemView = Backbone.View.extend() {

  tagName: 'li',

  log : function() {
    console.log(this.model.get("title");
  }

  render: function() {
        //Associate the element with the instance
    $(this.el).html(this.template(this.model.toJSON())).data( "viewInstance", this );
    return this;
  }
});
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...