1

I want to make a function with functionality like toJSON()'s functionality which returns and edits model.

My question is how to iterate on model's attribute and edit the specific value of the attribute you selected.

If have a model e.g:

Item = Backbone.Model.extend({
    defaults: {
        name: '',
        amount: 0.00
    },
    toHTML: function(){
        // i think this is the place where
        // where i can do that function?

        //
        console.log(this.attribute)
    }
});
var item = new Item;

item.set({name: 'Pencil', amount: 5}): 

item.toJSON();
-> {name: 'Pencil', amount: 5}

// this is the function
item.toHTML();
-> {name: 'Pencil', amount: 5.00}
Arslan Ali
  • 17,418
  • 8
  • 58
  • 76
jrsalunga
  • 409
  • 2
  • 8
  • 20

3 Answers3

5

You can iterate over an object using a for ... in loop and then use toFixed to format the number:

toHTML: function() {
    var attrs = { }, k;
    for(k in this.attributes) {
        attrs[k] = this.attributes[k];
        if(k === 'amount')
           attrs[k] = attrs[k].toFixed(2);
    }
    return attrs;
}

Note that amount will come out as a string but that's the only way to get 5.00 rather than 5 to come out. I'd probably leave the formatting up to the template and not bother with this toHTML implementation.

Demo: http://jsfiddle.net/ambiguous/ELTe5/

mu is too short
  • 426,620
  • 70
  • 833
  • 800
  • cooool! thanks for helping noobs like us! my plan is make the rendering lik e this --> this.$el.html(this.template(this.model.toHTML())); – jrsalunga Sep 27 '13 at 04:06
  • That will work and having a separate "serialize for templates" method (such as your `toHTML`) so that `toJSON` can be used to talk to the server is a good idea. I'd probably leave the `toFixed` call up to the template though. – mu is too short Sep 27 '13 at 04:13
  • yup! `toHTML` is for rendering purpose only. If ever the amount value in my `toHTML` is `1,550.00` the `toJSON` still have `1500.00` value, and the `toFixed` i tried to make a custom because `toFixed` not realible. anyway, thanks a lot for the help! cheers! – jrsalunga Sep 27 '13 at 06:06
4

If you want to iterate over a model's attributes, use the attributes hash:

// Inside your model's method
for(attr in this.attributes){
    console.log(attr, this.attributes[attr]);
}

Here's a jsFiddle using your example code.

Colin Brock
  • 21,267
  • 9
  • 46
  • 61
4

Though the answers provided here are correct and would do what you want. But I think the better way would be to use the underscore functions for this purpose. for simple looping you can use

_.each(list, iteratee, [context])

_.each(model.attributes, function(item, index, items){
  console.log(item);
  console.log(index);
})

you can also use specialized functions as per your specific need. Like if you are want to have a new result array as a result of applying some function on every element of your list, map can be the best option for you.

_.map(list, iteratee, [context])

var newList = _.map(model.attributes, function(item, index, list){
  return item * 5;
})

I would recommend you to go through the documentation of underscore and backbone for the best function for your need.