最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Trigger function on click if View has a certain class (backbone.js) - Stack Overflow

programmeradmin1浏览0评论

I have a div generated by a backbone.js view. When the user clicks on this div, a class active is added to the div and the function addToSet is executed.

Problem: I want another function to be triggered when the View's div has the class active. However, my attempt shown below always cause addToSet function to run when its clicked.

Now, I remove 'click': 'addToSet' from the events function, leaving only 'click .active': 'removeFromSet'. Clicking on the div does not cause anything to happen! Is this because the event handler cannot select the div of the view itself, just the elements inside it?

Any idea how I can solve this problem? Thanks!

JS Code

SetView = Backbone.View.extend({
    tagName: 'div',
    className: 'modal_addit_set',

    template: _.template( $('#tpl_modal_addit_set').html() ),

    events: {
        'click': 'addToSet',
        'click .active': 'removeFromSet'
    },

    initialize: function(opts) {
        this.post_id = opts.post_id;
    },

    render: function() {
        $(this.el).html( this.template( this.model.toJSON() ) );
        if(this.model.get('already_added'))
            $(this.el).addClass('active');
        return this;
    },

    addToSet: function() {
        $.post('api/add_to_set', {
            post_id: this.post_id,
            set_id: this.model.get('id'),
            user_id: $('#user_id').val()
        });
    },

    removeFromSet: function() {
        $.post('api/remove_from_set', {
            post_id: this.post_id,
            set_id: this.model.get('id')
        });
    }
});

I have a div generated by a backbone.js view. When the user clicks on this div, a class active is added to the div and the function addToSet is executed.

Problem: I want another function to be triggered when the View's div has the class active. However, my attempt shown below always cause addToSet function to run when its clicked.

Now, I remove 'click': 'addToSet' from the events function, leaving only 'click .active': 'removeFromSet'. Clicking on the div does not cause anything to happen! Is this because the event handler cannot select the div of the view itself, just the elements inside it?

Any idea how I can solve this problem? Thanks!

JS Code

SetView = Backbone.View.extend({
    tagName: 'div',
    className: 'modal_addit_set',

    template: _.template( $('#tpl_modal_addit_set').html() ),

    events: {
        'click': 'addToSet',
        'click .active': 'removeFromSet'
    },

    initialize: function(opts) {
        this.post_id = opts.post_id;
    },

    render: function() {
        $(this.el).html( this.template( this.model.toJSON() ) );
        if(this.model.get('already_added'))
            $(this.el).addClass('active');
        return this;
    },

    addToSet: function() {
        $.post('api/add_to_set', {
            post_id: this.post_id,
            set_id: this.model.get('id'),
            user_id: $('#user_id').val()
        });
    },

    removeFromSet: function() {
        $.post('api/remove_from_set', {
            post_id: this.post_id,
            set_id: this.model.get('id')
        });
    }
});
Share Improve this question asked Jul 23, 2012 at 22:15 NyxynyxNyxynyx 63.7k163 gold badges507 silver badges856 bronze badges
Add a ment  | 

2 Answers 2

Reset to default 6

Have you tried to use a :not(.active) selector for one of your event delegates? This may help differentiate between the two scenarios.

Something like this:

events: {
   'click :not(.active)' : callback1
   'click .active' : callback2
}

These events:

events: {
    'click': 'addToSet',
    'click .active': 'removeFromSet'
}

don't work and you sort of know why. From the fine manual:

Events are written in the format {"event selector": "callback"}. The callback may be either the name of a method on the view, or a direct function body. Omitting the selector causes the event to be bound to the view's root element (this.el).

So your 'click': 'addToSet' binds addToSet to a click on the view's el itself but 'click .active': 'removeFromSet' binds removeFromSet to a .active element inside the view's el.

I think the easiest solution is to have a single event:

events: {
    'click': 'toggleInSet'
}

and then:

toggleInSet: function() {
    if(this.$el.hasClass('active')) {
        $.post('api/remove_from_set', {
            post_id: this.post_id,
            set_id: this.model.get('id')
        });
    }
    else {
        $.post('api/add_to_set', {
            post_id: this.post_id,
            set_id: this.model.get('id'),
            user_id: $('#user_id').val()
        });
    }
}

You could use an instance variable instead of a CSS class to control the branching in toggleInSet if that makes more sense.

发布评论

评论列表(0)

  1. 暂无评论