2013-08-16 3 views
3

Привет, ребята, я создаю базовое приложение в первый раз - и это будет здорово!Магистральные события DOM, срабатывающие несколько раз

Однако, я не думаю, что создаю виды для своей коллекции моделей правильно, и когда я привязываю события, они запускаются для каждого вида, когда я хочу, чтобы они стреляли только для одного.

Вот мой позвоночник код (фрагмент):

 (function(){ 

     Series = Backbone.Model.extend({ 
      defaults:{ 
       active:false 
      } 
     }); 

     SeriesGridItemView = Backbone.View.extend({ 
      el:'#model-grid', 
      defaults: { 
       active : false 
      }, 
      initialize: function(){ 
       this.render(); 
       this.listenTo(this.model, 'change', this.setState); 
      }, 
      render: function(){ 
       this.template = _.template($('#template-model-grid-item-view').html()); 
       this.view = $(this.template(this.model.toJSON())).appendTo(this.$el); 
      }, 
      setState: function(){ 
       this.active = this.model.get('active'); 
       this.view.toggleClass('active',this.active); 
      }, 
      events: { 
       'click':'toggle' 
      }, 
      toggle: function(e){ 
       e.stopPropagation(); 
       e.preventDefault(); 
       console.log('clicked'); 
       return false; 
      } 

     }); 

     SeriesCollection = Backbone.Collection.extend({ 
      model: Series, 
      setPrice : function(p){ 
       this.forEach(function(m){ 
        var active = 0; 
        _.each(m.get('vehicles'),function(v){ 
         if(v.price <=p){ 
          v.active = true; 
          active++; 
         } 
         else{ 
          v.active = false; 
         } 
        }); 
        m.set('active',active>0); 
       }); 
      } 
     }); 

     series = new SeriesCollection(window.BMW.data.series); 
     series.forEach(function(m,i){ 
      var c = i+1; 
      if(c > 3){ 
       c%=3; 
      } 
      m.set('column','1'); 
      new SeriesGridItemView({model:m}); 
     }); 
    })(); 

А вот JSON, который строит модели:

window.BMW.data.series = [ 
    { 
     seriesId:1, 
     name:'1 Series', 
     slug:'1-series', 
     order:0, 
     vehicles:[ 
      { 
       seriesId:1, 
       price:200 
      }, 
      { 
       seriesId:2, 
       price:300 
      } 
     ] 
    }, 
    { 
     seriesId:2, 
     name:'3 Series', 
     slug:'3-series', 
     order:1, 
     vehicles:[ 
      { 
       seriesId:1, 
       price:400 
      }, 
      { 
       seriesId:2, 
       price:500 
      } 
     ] 
    }, 
    { 
     seriesId:3, 
     name:'4 Series', 
     slug:'4-series', 
     order:3, 
     vehicles:[ 
      { 
       seriesId:1, 
       price:100 
      }, 
      { 
       seriesId:2, 
       price:300 
      } 
     ] 
    }, 
    { 
     seriesId:4, 
     name:'6 Series', 
     slug:'6-series', 
     order:4, 
     vehicles:[ 
      { 
       seriesId:1, 
       price:100 
      }, 
      { 
       seriesId:2, 
       price:300 
      } 
     ] 
    }, 
    { 
     seriesId:6, 
     name:'X3', 
     slug:'x3', 
     order:5, 
     vehicles:[ 
      { 
       seriesId:1, 
       price:500 
      }, 
      { 
       seriesId:2, 
       price:800 
      } 
     ] 
    } 
]; 

А вот мой шаблон взглядов

<script type="text/template" id="template-model-grid-item-view"> 
    <div id="series-<%=seriesId%>" class="grid-item-view column-<%=column%>"> 
     <div class="label"><%= name %></div> 
     <div class="thumbnail"> 
      <img src="/Content/themes/BMW/img/series/small/<%= slug %>.png"/> 
     </div> 
    </div> 
</script> 

Проблема - виды собраны правильно, но когда я нажимаю один вид, событие срабатывает во всех представлениях! Может ли кто-нибудь указать мне в правильном направлении?

Спасибо,

Джек

ответ

5

Поскольку вы опустили селектор в вашем events объект ваших взглядов применяется следующее

За опорной сети Documentation: Omitting the selector causes the event to be bound to the view's root element (this.el).

Проблема является каждый из связь SeriesGridItemViewclick событий до #model-grid, и каждый вид - это ребенок #model-grid. В вашем примере вы регистрируете события 5 кликов, и когда вы нажимаете на какое-либо ваше мнение, все 5 событий запускаются.

Без изменения какого-либо другого кода одним из решений является установка объекта events для возврата функции, чтобы вы могли указать селектор id для каждого из ваших видов.

events: function() { 
    var selector = '#series-' + this.model.get('seriesId'); // this id corresponds to your template id 
    var ev = {}; 
    ev['click ' + selector] = 'toggle'; 
    return ev; 
}, 

Другой вариант и один я предпочитаю, чтобы не указать #model-grid в качестве корневого элемента для всех ваших взглядов. Это будет в конечном итоге выглядит как: demo

SeriesGridItemView = Backbone.View.extend({ 
    // remove the following line 
    el:'#model-grid', 

    // .. all else is the same ../ 
}); 

series = new SeriesCollection(window.BMW.data.series); 
    series.forEach(function(m,i){ 
    var c = i+1; 
    if(c > 3){ 
     c%=3; 
    } 
    m.set('column','1'); 
    $('#model-grid').append(new SeriesGridItemView({model:m}).el); 
}); 

полутуши suggetion

  1. В вашей render функции, нет необходимости создавать переменную, вы можете получить доступ к элементу с помощью $:

    render: function(){ 
        this.template = _.template($('#template-model-grid-item-view').html()); 
        this.$el.append(this.template(this.model.toJSON()))); 
    }, 
    setState: function(){ 
        this.active = this.model.get('active'); 
        this.$el.toggleClass('active',this.active); 
    }, 
    
+0

Спасибо, мой друг! Отлично. Мне нравится StackOverflow! – JackMahoney

Смежные вопросы