简体   繁体   中英

Backbone click event on class inside view

I'm new to backbone.js and just wondering how to make a click event happen on only one view? At the moment I add multiple TimelineView's and when I click on the .delete of one, it seems to alert the name for all of them?

TimelineView = Backbone.View.extend({

    initialize: function(){
        this.render();
    },

    template: Handlebars.compile($("#timeline-template").html()),

    render: function(){
        var self = this;
        var output = self.template(self.model.toJSON());
        self.$el.append(output);
        return self;
    },

    events: {
        'click .property-name' : 'alertName',
        'click .delete' : 'deleteProperty'
    },

    alertName: function(e){
        var name = this.model.get("name");
        alert(name)
        console.log(e);
    },

    deleteProperty: function(e){
        var name = this.model.get("name");
        alert("Deleting " + name)
        this.model.destroy();
    },
});

EDIT:

Sorry I had no idea it was more than just the View controlling how this worked.

So the models

var Timeline = Backbone.Model.extend({
    //object properties would go here
    initialize: function(){
        console.log('A new timeline has been created!');
        console.log(this.cid);
        this.on("change", function(){
            console.log('Timeline Changed:');
            console.log('Previous attributes: ' + JSON.stringify(this.previousAttributes()));
            console.log('New attributes: ' + JSON.stringify(this.attributes));

        });
    },
    defaults: {
        name: 'CSS property nice name',
        CSSProperty: 'CSS property name',
        prefixes: [],
    }

});

And beneath them how they are added:

var t = new Timeline({
    "name":"Foo",
});;
var q = new Timeline({
    "name":"Opacity",
    "CSSProperty":"opacity"
});
var r = new Timeline({
    "name":"Height",
    "CSSProperty":"height"
});
var a = new Animation;
var ts = new Timelines;

ts.add([t,q,r]);

var tv = new TimelineView({
    model: t,
    el: '#timelineView',
});

$("#addProperty").click(function(){
    console.log('added')
    var p = new Timeline({
        "name":"Pow",
        "CSSProperty":"awesome!"
    })
    var ts = new TimelineView({
        model: p,
        el: '#timelineView',
    })
})

Full (rubbish) app here: http://djave.co.uk/hosted/stackoverflow/backbone/

Listeners specified in the events object are only bound to the elements contained within this.$el (which you can set using this.setElement() inside the view). Binding multiple views to the same element will always combine the event listeners and it is not good practice. You should probably set this.$el for each view to the html generated by handlebars for your model.

rewriting your render function will likely fix your issue:

render: function(){
        var output = this.template(this.model.toJSON());
        this.setElement(output.appendTo($('#timelineView'))
        return this;
}

You can pass the #timelineView container as usual and store it as a variable inside the view but this ensures that each view is limited to the section representing its model and not the entire view container.

You can fix that by removing the el parameter :

var tv = new TimelineView({
    model: t,
    //el: '#timelineView',
});

$("#addProperty").click(function(){
    console.log('added')
    var p = new Timeline({
        "name":"Pow",
        "CSSProperty":"awesome!"
    })
    var ts = new TimelineView({
        model: p,
        //el: '#timelineView',
    })
})

and in your view render :

render: function(){
    var self = this;
    var output = self.template(self.model.toJSON());
    self.$el.append(output);
    $('#timelineView').append(self.$el);
    return self;
},

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM