Buzut
Buzut

Reputation: 5153

Backbone getting model for a clicked element

Say I have a collection of sportsmen. I juste display their names and when there's a click on a name, I'd like to dislay some more details. But that implies I have to retrieve the associate model.

So I have a model, a collection and then two views, one that takes care of rendering each individual name, and the other one manages the list of those names. And then I'll have to create a view to display the details of the clicked sportsman.

But I can't figure out how to retrive the associate model. If I place my event in the view that manages the list, it triggers on click but there's an error saying that the model is undefined.

And if the event listener is located in the view that renders each individual name, it doesn't do anything on click.

Here's my code :

Index.html

<script id="nameListTemplate" type="text/template">
    <%= first %> <%= last %>
</script>
<script id="contactTemplate" type="text/template">
    <ul>
    <li><%= first %></li>
    <li><%= last %></li>
    <li><%= age %></li>
    <li><%= sport %></li>
    <li><%= category %></li>
    </ul>
</script>
<script src="js/lib/jquery.min.js"></script>
<script src="js/lib/underscore-min.js"></script>
<script src="js/lib/backbone-min.js"></script>

<script src="js/models/sportsManModel.js"></script>
<script src="js/collections/sportsMenCollection.js"></script>
<script src="js/views/nameView.js"></script>
<script src="js/views/nameListView.js"></script>
<script src="js/app.js"></script>

<ul id="sportsMenName"></ul>

<div id="sportsManDetails"></div>

sportsManModel.js

var app = app || {};

app.SportsManModel = Backbone.Model.extend({});

sportsMenCollection.js

var app = app || {};

app.SportsMenCollection = Backbone.Collection.extend({
    model: app.SportsManModel
});

nameView.js

var app = app || {};

app.NameView = Backbone.View.extend({
    tagName: 'li',
    className: 'sportsMan',
    template: _.template($('#nameListTemplate').html()),

    /*events: {
        'click .sportsMan': 'showSportsManDetails'
    },
    // here it doesn't work at all
    showSportsManDetails: function(e){
        alert(this.model.get('first'));  
    },*/

    render: function(){
        this.$el.append(this.template(this.model.attributes));

        return this;
    }
});

nameListView.js

var app = app || {};

app.NameListView = Backbone.View.extend({
    el: '#sportsMenName',

    initialize: function(sportsMen){
        this.collection = new app.SportsMenCollection(sportsMen);
        this.render();
    },

    /*events: {
        'click .sportsMan': 'showSportsManDetails'
    },
    // here it says that this.model is undefined
    showSportsManDetails: function(e){
        alert(this.model.get('first'));  
    },*/

    render: function(){
        this.collection.each(function(sportsMen){
            this.renderContact(sportsMen);
        }, this)
    },

    renderContact: function(sportsMen){
        var nameView = new app.NameView({
            model: sportsMen   
        });
        this.$el.append(nameView.render().el);
    }
});

Upvotes: 0

Views: 80

Answers (2)

Eugene Glova
Eugene Glova

Reputation: 1553

The first problem is that you have a view for li.sportsMen element so you don't need to use class .sportsMen in events at all.

And second problem you had wrong method name for click event showSportsManDetails but should be showContactDetail as you have showContactDetail method or rename method name to showSportsManDetails instead.

app.NameView = Backbone.View.extend({
...
    events: {
        'click': 'showSportsManDetails'
    },

    showSportsManDetails: function(e){
        alert(this.model.get('first'));  
    },

Here is a working example http://jsbin.com/yutaduvokehu/1/edit

Upvotes: 2

StateLess
StateLess

Reputation: 5402

i think the problem may be with the scope , try adding this initalize function in nameView :

initailize : function(){
   _.bindAll(this,'showContactDetail');
}

Upvotes: 1

Related Questions