简体   繁体   中英

Backbone - aggregator event firing for all models in collection

I'm trying to use the event aggregator to fire a method off of a model's view. The problem is, when I fire the update or save method for the ItemView , it iterates through all models in the collection. How do I get it to not only fire properly for the model which the view represents (or a new modal in the save method's case), but also prevent it from firing for every model in the collection?

This application consists of a collection of Items , each Item has a model which is rendered into an ItemView and listed on the page. If a user clicks the edit item icon, then a ModalView is instantiated and the current Item model data is injected into the ModalView .

The ModalView which gets loaded with a template for the respective task. For this instance, i'm loading a template to edit the Item . Here's a summary of the relevant code:

var ModalView = Backbone.View.extend({
  tagName: "section",
  className: "modal",
  events: {
    'click .close': 'close',
    'click .minimize': 'minimize',
    'click .maximize': 'maximize',
    'click .save-item': 'saveItem',
  },
  html: null,
  initialize: function(options) {
    this.template = _.template(ModalTemplate);
    this.vent     = options.vent;
  },
  saveItem: function() {
    this.vent.trigger('item.save');
  },
});

The item collection's view is here:

var ItemsView = Backbone.View.extend({
  tagName: 'ul',
  className: 'item-items',
  render: function(){
    var self = this;
    // Make it flex GRRRR
    this.$el.addClass('flex-item');

    this.collection.each(function(item) {
      var date = item.get('created_at');
      var itemView = new ItemView({ model: item, vent: App.vent });
      this.$el.append(itemView.render().el);
    }, this);
    return this;
  }
});

Finally, the item model's view which contains the edit method that fires the ModalView

var ItemView = Backbone.View.extend({
  tagName: 'li',
  className: 'item',
  events: {
    'click .edit-item': 'edit'
  },
  initialize: function(options) {
    this.template = _.template(ItemTemplate);
    options.vent.bind("item.save", this.save);
    options.vent.bind("item.update", this.update);
  },
  save: function() {
    var attributes, item;
    item = new App.api.item.model();
    attributes = getMeta(true);
    item.save(attributes)
    .done(function(res) {
      Ui.modal.destroy();
      // Re-render items
      App.routers.main.render.User.sidebar();
      App.routers.main.render.Item.items(function() {
        Ui.resizeContent();
      });
    })
    .fail(function(res) {
      console.log(res);
    });
  },
  update: function() {
    console.log('update') // fires App.api.item.collection.length times
    var attributes, item;
    item = App.api.item.collection.get(App.rendered.modal.$el.data('id'));
    attributes = getMeta();
    item.save(attributes)
    .done(function(res) {
      Ui.modal.destroy();
      // Re-render items
      App.routers.main.render.Item.items(function() {
        Ui.resizeContent();
      });
    })
    .fail(function(res) {
      console.log(res);
    });
  },
  edit: function() {
    Ui.modal.new(ItemModalTemplate, this.model.attributes);
    App.rendered.modal.$el.attr('data-id', this.model.get('_id'));
    // New Editor
    var editor  = document.querySelector('#item-editor');

    window.editor = new MediumEditor(editor, editorOptions);
  }
});

Obviously I'm missing something fundamental here because console.log('update') in the save method of the ItemView fires for every item in the collection. What I was trying to do was keep the logic for save , and update in the view for the Item for organizational purposes.

Many thanks.

Instead of options hold the model itself in the ItemModelView so you can call save directly without need for events.

Replace this Ui.modal.new(ItemModalTemplate, this.model.attributes); with UI.modal.new(ItemModalTemplate, this.model) , and this this.vent.trigger('item.save'); with this.model.save()

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