Pergunta

I'm trying to reach a collection instance with the this keyword, when iterating through its models. Here is my test code:

myModel = Backbone.Model.extend({

    url: 'model.com'
});    

myCollection = Backbone.Collection.extend({

    model: myModel,
    url: 'collection.com',

    iterateAll: function(){
        this.each(function(item){
             console.log(this.url);
             console.log(item.url);
        });
    }
});

mod = new myModel();
col = new myCollection(mod);

col.iterateAll();

This code outputs:

undefined
model.com

How can I reference the collection correctly when using this.url? I want the output to read collection.com not undefined.

Foi útil?

Solução

this is pretty weird in JavaScript.

iterateAll: function() {
    var self = this; // _this is also common
    this.each(function(item) {
         console.log(self.url);
         console.log(item.url);
    });
}

Basically, JavaScript doesn't formally distinguish between methods and functions. As a result, every function invocation -- even simple anonymous callbacks like these -- gets its own this value. But this very frequently isn't...what anyone wants ever. So you can hold onto the "useful" value of this in a temporary variable and reference it in the callback.

This is so common that it's a feature of CoffeeScript via the => syntax, and it's going to be a feature of ES6. Until then...temp variables are we've got.

Outras dicas

Do this instead:

...
iterateAll: function(){
    var me = this;
    me.each(function(item){
         console.log(me.url);
         console.log(item.url);
    });
}
...

More info on this scope. http://javascriptplayground.com/blog/2012/04/javascript-variable-scope-this/

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top