lkurylo
lkurylo

Reputation: 1641

backbone - event not fired on selected element changed

I'm generating a drop down list from Backbone.View.
After attaching it to the DOM, change event is not fired. The delegateEvents doesn't fixes it. Can somebody show me where the blind spot is?

Model and collection:

App.Models.DictionaryItem = Backbone.Model.extend({
        default: {
            key: '',
            value: '', id: 0
        }
    });

    App.Collections.Dictionary = Backbone.Collection.extend({
        model: App.Models.DictionaryItem,
        initialize: function (models, options) {

        },
        parse: function (data) {
            _.each(data, function (item) {
             //   if(item){
                var m = new App.Models.DictionaryItem({ key: item.code, value: item.name });
                this.add(m);
           // }
            }, this);
        }
    });

Views:

App.Views.ItemView = Backbone.View.extend({
        tagName: 'option',
        attributes: function () {
            return {
                value: this.model.get('key')
            }
        },
        initialize: function () {
            this.template = _.template(this.model.get('value'));
        },
        render: function () {
            this.$el.html(this.template());
            return this;
        }
    });

    App.Views.CollectionView = Backbone.View.extend({
        tagName: 'select',
        attributes: {
            'class': 'rangesList'
        },
        events: {
            'change .rangesList': 'onRangeChanged'
        },
        initialize: function (coll) {
            this.collection = coll;
        },
        render: function () {
            _.each(this.collection.models, function (item) {
                this.$el.append(new App.Views.ItemView({ model: item }).render().el);
            }, this);
           // this.delegateEvents(this.events);
            return this;
        },
        selected: function () {
            return this.$el.val();
        },
        onRangeChanged: function () {
            alert('changed');
        }
    });

Rendering:

var coll = new App.Collections.Dictionary(someData, { parse: true });
var v= new App.Views.CollectionView(coll);
var vv=v.render().el;

//   new App.Views.CollectionView(coll).render().el;
$('body').append(vv)

Upvotes: 1

Views: 354

Answers (1)

mu is too short
mu is too short

Reputation: 434685

The tagName and attributes on CollectionView:

tagName: 'select',
attributes: {
    'class': 'rangesList'
},

say that the el will be <select class="rangesList">. But your events:

events: {
    'change .rangesList': 'onRangeChanged'
},

are listening to 'change' events from a .rangesList inside the view's el. From the fine manual:

Events are written in the format {"event selector": "callback"}. [...] Omitting the selector causes the event to be bound to the view's root element (this.el).

So you're trying to listen for events from something that doesn't exist. If you want to listen for events directly from the view's el then leave out the selector:

events: {
    'change': 'onRangeChanged'
}

Upvotes: 1

Related Questions