集合委派事件



我有两个视图,一个是ListView,另一个是ListRow视图。ListView负责显示UI并处理搜索框上的事件。搜索方法是在更改时触发的,在Backbone.search()的帮助下,我得到了一组匹配的模型。

但是,当呈现ListRow视图时(在搜索之后),事件不会绑定到它们。我曾尝试在filtered_events.each块内的ListView processSearch方法中调用view.deleteEvents(),但这似乎根本没有帮助。以下是我的观点的源代码。

ListVIew.js

CheckinApp.Views.ListView = Backbone.View.extend({
properties: {
    list_title: '',
    event_id: null,
    list_type: ''
},
list_element: '.chk_list_main',
template: null,
collection: null,
el: '.content',
events: {
    "keyup #search": "processSearch",
    "change #search": "processSearch"
},
"processSearch": function(e) {
    var html = '';
    var search_string = $(e.currentTarget).val().toLowerCase();
    var filtered_events = this.collection.search(search_string, 'name');
    if(search_string == '') filtered_events = this.collection;
    console.log('searching tickets for '' + search_string + '' and found ' + filtered_events.length + ' matching tickets');
    filtered_events.each(function(model) {
        var list_template = (this.properties.list_type == 'event') ? '#list_row_event' : '#list_row_ticket';
        var view = new CheckinApp.Views.ListRow({"model": model, list_template: list_template});
        var rendered_view = view.render().el;
        html += '<div class='chk_list'>' + $(rendered_view).html() + '</div>';
    }, this);
    if(html == '') {
        $(this.list_element).html($('#search_no_results').html());
    } else {
        $(this.list_element).html(html);
    }
    return this;
},
initialize: function(data) {
    if(this.properties.list_type == 'ticket' && data.event_id == null) {
        Backbone.history.navigate("#", true);
    }
    this.properties.list_title = data.list_title;
    this.properties.event_id = data.event_id;
    this.properties.list_type = data.list_type;
    if(data.list_type == 'event') {
        this.collection = new CheckinApp.Collections.Events();
    } else {
        this.collection = new CheckinApp.Collections.Tickets({"event_id": data.event_id});
    }
    this.template = _.template($('#listview').html())(this.properties);
    this.listenTo(this.collection, 'add', this.add_list_row);
    this.listenTo(this.collection, 'reset', this.add_all);
    this.collection.fetch();
},
render: function() {
    var logo = $('body').find('logo');
    var navigation = $('body').find('.navig');
    if(this.properties.list_type == 'event') {
        navigation.remove();
        logo.text(CheckinApp.session.user.brand);
    } else {
        logo.text(CheckinApp.session.user.current_venue);
    }
    $(this.el).html(this.template);
    return this;
},
add_list_row: function(model) {
    var list_template = (this.properties.list_type == 'event') ? '#list_row_event' : '#list_row_ticket';
    var view = new CheckinApp.Views.ListRow({"model": model, list_template: list_template});
    view.delegateEvents();
    var rendered_view = view.render().el;
    $(".chk_list_main").append(rendered_view);
},
add_all: function() {
    this.collection.each(this.add_list_row, this);
}
});

ListRow.js

CheckinApp.Views.ListRow = Backbone.View.extend({
tagName: "div",
className: "chk_list",
template: null,
events: {
    "click .checkd_in": "toggleCheckin",
    "click .undo_checkd_in": "toggleCheckin",
    "click .select_event, .txt_chk_text": "viewListsForEvent"
},
initialize: function(data) {
    this.model = data.model;
    this.template = _.template($(data.list_template).html());
    this.listenTo(this.model, 'change', this.render);
    this.listenTo(this.model, 'destroy', this.remove);
},
render: function() {
    (this.model instanceof CheckinApp.Models.Event) ? this.renderEventRow() : this.renderTicketRow();
    return this;
},
renderEventRow: function() {
    this.$el.html(this.template(this.model.attributes));
},
renderTicketRow: function() {
    if(this.model.get('checked_in') == 1) $(this.el).addClass('chk_undo_list');
    else $(this.el).removeClass('chk_undo_list');
    this.$el.html(this.template(this.model.attributes));
},
toggleCheckin: function(e) {
    e.preventDefault();
    this.model.save({
        "checked_in": (this.model.get('checked_in') == 0) ? "1" : "0"
    });
},
viewListsForEvent: function(e) {
    e.preventDefault();
    CheckinApp.session.user.current_venue = this.model.get("venue_name");
    CheckinApp.session.user.current_event = $(e.currentTarget).find('a').data('event');
    Backbone.history.navigate('guestlist', true);
}
});

我在processSearch方法中对视图进行字符串化,将其更改为以下内容修复了事件绑定问题。

    "processSearch": function(e) {
    var search_string = $(e.currentTarget).val().toLowerCase();
    var filtered_events = this.collection.search(search_string, 'name');
    if(search_string == '') filtered_events = this.collection;
    var results = [];
    filtered_events.each(function(model) {
        var item_row = new CheckinApp.Views.ListRow({"model": model, list_template: this.properties.list_template});
        results.push(item_row.render().el);
    }, this);
    if(results.length == 0) {
        $(this.list_element).html($('#search_no_results').html());
    } else {
        $(this.list_element).html(results);
    }
    return this;
},

最新更新