2

I have this collection:

var items = new bb.Collections.QuotesCollection([
    {id: 1, name: "item 1", units: []},
    {id: 2, name: "item 2", units: []},
    {id: 3, name: "item 3", units: []}
]);

And then I output the array "units" like so:

if(this.model.get('units').length){
        $(this.el).append('<strong>Units</strong>');
        $(this.el).append('<ul>');
        for(x in this.model.get('units')){
            $(this.el).append('<li class="unit">' + this.model.get('units')[x] + '</li>');
        }
        $(this.el).append('</ul>');
    } 

The code above is only POC stuff, so no formal templating as yet.

events: {
    "keypress #addUnit" : "addUnit",
    "dblclick .unit" : "deleteUnit"
},

deleteUnit: function(){
    this.render(); // what do I put here!?
}

What approach do I take to delete an item (the clicked one) from the "units" array?

3 Answers 3

2

this is the quick and dirty method:

Assuming the Array's order is not changed through any other medium, you could do

deleteUnit: function() {
  // get the index of the li you are clicking
  var index = $('.unit').index(this);
  this.model.get('units').splice(index, 1);
  this.render();
}

This way you have to remember to empty your view element before every render

render: function() {
  this.$el.empty();
  ...
  // business as usual
}
Sign up to request clarification or add additional context in comments.

4 Comments

As far as you can see, are there any drawbacks to your "quick and dirty" method? Would I be better following the answer below from @mrappleton?
Well, the drawbacks are that you have to remember to keep the ui up to date all the time. So every sort, addition and deletion operation should come with a render. Otherwise I see no drawbacks, some purists might have a problem with extracting the index from the DOM. mrappleton's solution doesn't really answer your problem, because your units are not models
also I see no point making a model out of each unit the way this is portrayed, although the situation changes if each unit is for example a reference to a model (like unit id, etc)
A downside of this approach is that modifying an array attribute in-place won't trigger a "change" event. You'd have to trigger the change events by hand (ick) or pull the array out, make a copy, splice the copy, and then set the new array; doing that outside the model is more ick but adding a remove_unit method to the model that does all that would be fairly clean.
1

First, you probably want to have a view object for each model, so you'd have a collection view which owns the <ul> and looks like this:

var ParentView = Backbone.View.extend({
  render: function() {
    var html = '<ul></ul>'; // make your html here (usually with templates)
    this.$el.append(html);        
    this.collection.each(_.bind(this.initChild, this));
    return this; // so we can chain calls if we want to.
  }
  initChild: function(model) {
    var child = new ChildView({ model: model });
    // this.$() is scoped to the view's el property
    this.$('ul').append(child.render().el);
  }
});

You'd then set up the child views something like this:

var ChildView = Backbone.View.extend({
  events: { 'click .delete', 'deleteModel' },
  render: function() {
    var html = '';// make your html here (usually with templates)
    this.$el.append(html);
    return this;
  },
  deleteModel: function(ev){
    ev.preventDefault();
    // Removes form the collection and sends an xhr DELETE
    this.model.destroy(); 
    this.$el.remove();
  }
});

The call to Model#destroy will take care of removing it from the collection and sending a DELETE to the server (assuming you have a URL set up in your collection/model).

3 Comments

So, to clarify, I would create a new model and a new view for each "units" array item? Would I also need a collection as well? (n00b concepts)
this answer mistakenly assumes that the units are models which are stored in a collection
Ah good point, units are just a dumb array on the model aren't they. In that case I would either refactor them to be a proper Collection, or go with something like 'quick & dirty' below. Which depends on how much more you want to do with units I guess.
0

As far as i understand you need to delete item from model

Person = Backbone.Model.extend({ initialize: function() { alert("Welcome to this world"); } }); var person = new Person({ name: "Thomas", age: 67}); delete person.name

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.