简体   繁体   中英

binding this in a jQuery callback in backbone.js

I'm having trouble with this in a backbone.js project.

This is my view:

app.SomeView = Backbone.View.extend({
  render: function() {
    var that = this;
    $.getJSON(someURL, function(result) {
      that.property = result.something;
    });

    return this;
  }
})

Inexplicably, inside the getJSON callback that.property is set, but as soon as that function is finished - ie at return this - that.property equals undefined , same as this.property .

What am I doing wrong?

As mentioned in my comment, $.getJSON is asynchronous. The render function continues to execute while $.getJSON fetches the appropriate URL, so return this; ends up executing before that.property = result.something

Not sure why you are not using Models. Answering to your question, there are different solutions, the first one:

Using events:

app.SomeView = Backbone.View.extend({
  render: function() {
    var that = this;
    $.getJSON(someURL, function(result) {
      that.property = result.something;
      that.trigger('DataLoaded', that);
    });

    return this;
  }
});
var view = new app.SomeView();
view.on('DataLoaded', function(theView){ 
  console.log( theView );
});

Second one, you need to add a callback and pass it:

app.SomeView = Backbone.View.extend({

  render: function(callback) {
    var that = this;
    $.getJSON(someURL, function(result) {
      that.property = result.something;
      callback(that);
    });
    return this;
  }
});
var view = new app.SomeView();
view.render( function(theView){ 
  console.log( theView );
});

My answers was written for fix the question that you created. But for a long term improvement, do you know that Models has a fetch method that basically loads JSON from the server and associate it the Model? http://backbonejs.org/#Model-fetch This is how I will load the JSON:

app.SomeModel = Backbone.Model.extend({
  urlRoot : someURL
});
app.SomeView = Backbone.View.extend({
  initialize : function(){
     this.model.on('change', this.render);
  },
  render: function() {
    console.log( this.model.toJSON() );
    return this;
  }
});
var view = new app.SomeView(new app.SomeModel());
view.model.fetch();

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