2016-05-17 3 views
0

Скажет, мой шаблон выглядит следующим образом:Backbone - получить определенную модель из коллекции, итерированная в шаблоне

<script type="text/template" id="template"> 
    {{#each []}} 
    <div>{{this.id}}</div> 
    <div>{{this.name}}</div> 
    <div>{{this.description}}</div> 
    <input id="my-btn" type="button">Button</input> 
    {{/each}} 
</script> 

модель и коллекция:

var Item = Backbone.Model.extend({ 
    defaults: { 
     id: null, 
     name: '', 
     description: '' 
    } 
}); 

var ItemCollection = Backbone.Collection.extend({ 
    model: Item, 
    url: function() { 
     return '/items'; 
    } 
}); 

И в представлении Я просто забираю предметы и показываю их:

var ItemsView = Backbone.View.extend({ 
    el: $('#items'), 
    template: Handlebars.compile($('#template').html()), 
    items: new ItemCollection(), 
    initialize: function() { 
     var self = this; 
     this.items.fetch({success: function() { 
      self.render(); 
     }}); 
    }, 
    render: function() { 
     var items = new ItemCollection(); 
     var html = this.template(items.toJSON()); 
     this.$el.html(html); 
    } 
}); 

Каждый элемент с его полями в шаблоне имеет свою собственную кнопку.

Прямо сейчас мне нужно добавить функциональность, которая будет срабатывать при нажатии кнопки в шаблоне, поэтому нажмите кнопку, чтобы какая-то функция должна была получить элемент, связанный с кнопкой в ​​шаблоне.

Как я могу это сделать?

+1

'id' атрибуты должны быть уникальными или не имеют действительного HTML. Исправьте это сначала, а затем потратите некоторое время на [точное руководство] (http://backbonejs.org/#View-events). –

+0

Возможный дубликат [получить щелчок модели и добавить к другой коллекции в позвоночник] (http://stackoverflow.com/questions/9885341/get-clicked-model-and-add-to-other-collection-in-backbone) –

ответ

1

Вот один из способов добиться того, что вы просите - просто добавьте обработчик кликов в хэш-код events (http://backbonejs.org/#View-events). Я добавил атрибуты тире данных к кнопкам, чтобы в обработчике кликов вы могли определить, на какую кнопку щелкнули/модель, с которой нужно действовать.

var ItemView = window.Backbone.View.extend({ 
    tagName: 'div', 
    template: Handlebars.compile($('#template').html()), 
    events: { 
      'click .item-btn': 'clickHandler' 
    }, 
    render: function() { 
     this.$el.html(this.template({ 
     items: collection.toJSON() 
     })); 
     return this; // backbone convention -- return the view 
    }, 
    clickHandler: function(e) { 
      alert($(e.target).data().itemId + ' clicked'); 
    } 
    }); 

выше вид принимает следующий шаблон:

<script type="text/template" id="template"> 
     {{#each items}} 
     <div>{{this.id}}</div> 
     <div>{{this.name}}</div> 
     <div>{{this.description}}</div> 
     <input class="item-btn" data-item-id="{{this.id}}" type="button" value="Button {{this.id}}"></input> 
     {{/each}} 
    </script> 

Вот рабочая демонстрация: https://jsfiddle.net/9cgzcc3y/

Другой способ сделать это (и тот, который я предпочитаю лично) является создание единой для каждой модели. Таким образом, каждое представление будет поддерживаться отдельной моделью.

var ItemView = window.Backbone.View.extend({ 
    tagName: 'div', 
    template: Handlebars.compile($('#template').html()), 
    events: { 
      'click .item-btn': 'clickHandler' 
    }, 
    render: function() { 
     this.$el.html(this.template(this.model.toJSON())); 
     return this; 
    }, 
    clickHandler: function() { 
     alert('clicked: ' + this.model.get('id')); 
    } 
    }); 

    var ItemsView = window.Backbone.View.extend({ 
    tagName: 'div', 
    initialize: function() { 
     this.collection = collection; 
    }, 
    render: function() { 
     var frag = document.createDocumentFragment(); 
     this.collection.each(function(model) { 
      frag.appendChild(new ItemView({model: model}).render().el); 
     }); 
     this.$el.append(frag); 
     return this; 
    } 
    }); 

    $('#items').append(new ItemsView().render().$el); 

Вот рабочий пример этой альтернативы: https://jsfiddle.net/45kuhp7h/

+0

Спасибо, я использовал первый вариант, и он сработал. –

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