loorko
loorko

Reputation: 39

Why I could not remove a model from a Backbone collection?

When I try to remove a model from a collection, I get an error:

Cannot read property 'removed' of undefined

If I click two times, it works.

var PhoneFormItemView = Marionette.View.extend({
  className: 'row',
  template: _.template('<div><input type="text" value="<%- type %>"><input type="text" value="<%- local_number %>"></div><button type="button" class="remove_phone_number-btn">Remove</button>'),
  triggers: {
    'click .remove_phone_number-btn': 'remove:item'
  }
});
var PhoneFormListView = Marionette.CollectionView.extend({
  className: 'phone-form-item',
  childView: PhoneFormItemView,
  onChildviewRemoveItem: function(childView) {
    this.collection.remove(childView.model);
    this.render();
  }
});

var phoneNumberView = Marionette.View.extend({
  el: '#phone-number',
  template: _.template('<div id="phone-number-region">asd</div>'),
  regions: {
    phoneNumberRegion: {
      el: '#phone-number-region'
    }
  },
  onRender: function() {
    var ModelPhoneNumber = Backbone.Model.extend();
    var CollectionPhoneNumber = Backbone.Collection.extend({
      model: ModelPhoneNumber
    });
    this.collectionPhoneNumber = new CollectionPhoneNumber();
    this.collectionPhoneNumber.add({
      type: 'bussines',
      country_code: 12,
      carrier_code: 34,
      local_number: 56789,
      extension: 444
    });
    this.collectionPhoneNumber.add({
      type: 'personal',
      country_code: 10,
      carrier_code: 20,
      local_number: 987564,
      extension: 23
    });
    this.showChildView('phoneNumberRegion', new PhoneFormListView({
      collection: this.collectionPhoneNumber
    }));
  }
});

var view = new phoneNumberView().render();
<div id="phone-number"></div>

<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.2.4/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/underscore.js/1.8.3/underscore-min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/backbone.js/1.2.3/backbone-min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/backbone.radio/2.0.0/backbone.radio.min.js"></script>

<script src="https://cdnjs.cloudflare.com/ajax/libs/backbone.marionette/3.2.0/backbone.marionette.min.js"></script>

Upvotes: 0

Views: 369

Answers (2)

Zac
Zac

Reputation: 1303

I suggest you can achieve this within your PhoneFormItemView. You can just create an event on click of .remove_phone_number-btn by using the destroy method of the model, as explained in the below code:

var PhoneFormItemView = Marionette.View.extend({
  className: 'row',
  template: _.template('<div><input type="text" value="<%- type %>"><input type="text" value="<%- local_number %>"></div><button type="button" class="remove_phone_number-btn">Remove</button>'),
  events: {
    'click .remove_phone_number-btn': 'removePhoneNumberHandler'
  },
  removePhoneNumberHandler: function() {
      this.model.trigger('destroy', this.model);
  }
});
var PhoneFormListView = Marionette.CollectionView.extend({
  className: 'phone-form-item',
  childView: PhoneFormItemView
});

The reason of using this.model.trigger('destroy', this.model); and NOT this.model.destroy(); is that the later will send a server call to remove the model even from the server, while the former will delete the model from within the collection and remove that PhoneFormItemView from the DOM and update the collection.

Upvotes: -1

loorko
loorko

Reputation: 39

With Backbone 1.3.3 it works.

From the Marionette 3.2.0 readme:

Compatibility and Requirements

MarionetteJS currently works with the following libraries:

  • jQuery v1.8+
  • Underscore v1.8.3
  • Backbone v1.3.3
  • Backbone.Radio v2.0.0+

From the Backbone changelog:

1.3.3 — Apr. 5, 2016

[...]

  • Added options.changes to Collection "update" event which includes added, merged, and removed models.

[...]

Upvotes: 2

Related Questions