这个fetch调用问题

this fetch call issue

本文关键字:问题 调用 fetch 这个      更新时间:2023-09-26

在主干视图中有以下代码:

var BookView = Backbone.View.extend({
initialize: function() {
    this.render();
},
render: function() {
  this.model.fetch({
    success : function(model, resp, opt) {
       alert(this.$el.html() ); //THIS ONE DOESN'T WORK?
    }
  });
  alert(this.$el.html() ); // THIS ONE WORKS FINE
}
});

我有两个alert(this.$el.html() );调用,一个在取外,一个在取内。但是由于某种原因,在fetch调用之外的那个可以工作,但是在fetch调用内部的那个返回了一个错误:Uncaught TypeError: Cannot read property 'html' of undefined

success内部,this不再是View(严格模式下是undefined,否则是window)。

要解决这个问题,您可以使用常见的var that = this习惯用法;有关此习语的更多信息,请参阅此处:'var that = this;'在JavaScript中是什么意思?

var BookView = Backbone.View.extend({
initialize: function() {
    this.render();
},
render: function() {
  var that = this; // define here
  this.model.fetch({
    success : function(model, resp, opt) {
       alert(that.$el.html() ); // Use that instead of this here.
    }
  });
  alert(this.$el.html() ); // THIS ONE WORKS FINE
}
});

替代选项:参见.bind() -一个体面的资源:https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/bind

render: function() {
  this.model.fetch({
    success : function(model, resp, opt) {
       alert(that.$el.html() ); 
    }.bind(this) // this.model.fetch.success now has bound 'this' permanently for any call to success from this method form here on out. 
  });
  alert(this.$el.html() );
}

请记住,JavaScript函数中的this取决于函数如何调用,而不是如何定义或在何处定义(当然绑定函数除外)。Model#fetch文档没有为success回调指定任何特定的this,因此它可能被称为普通函数(即thissuccess回调中的window)。结果是this.$el在你的success回调中是undefined

您有多种选择:

  1. 使用标准的var _this = this技巧将所需的上下文隧道到回调中:

    var _this = this;
    this.model.fetch({
      success : function(model, resp, opt) {
        alert(_this.$el.html());
      }
    });
    
  2. 使用Function.prototype.bind使用绑定函数作为回调:

    this.model.fetch({
      success : function(model, resp, opt) {
        alert(this.$el.html());
      }.bind(this)
    });
    
  3. 使用_.bind将回调绑定到所需的this:

    this.model.fetch({
      success : _(function(model, resp, opt) {
        alert(this.$el.html());
      }).bind(this)
    });
    

那是因为你不能再访问'this'了,内部调用'this'实际上是引用回调函数。

尝试将'this'绑定到返回函数,或者将'this'设置为渲染范围内的变量'self'或其他。

1 -

render: function() {
  this.model.fetch({
    success : function(model, resp, opt) {
       alert(this.$el.html() );
    }
  }.bind(this)); //Passes 'this' along for execution on the callback. 
  alert(this.$el.html() );
}

2 -

render: function() {
  var self = this;
  this.model.fetch({
    success : function(model, resp, opt) {
       alert(self.$el.html() ); //the scope of 'self' makes it in here
    }
  };
  alert(this.$el.html() );
}

this在javascript中是当前上下文。因此,例如,如果success()将被调用为按钮的单击事件处理程序,那么this将是按钮。

试着检查success()方法中的this到底是什么。阅读关于闭包的优秀教程,例如:http://www.javascriptkit.com/javatutors/closures.shtml

作为一个快速的解决方案,我建议这样更正:

render: function() {
  var that = this; // <<<<< Change 1
  this.model.fetch({
    success : function(model, resp, opt) {
      //alert(this.$el.html() ); //THIS ONE DOESN'T WORK?
      alert(that.$el.html() ); // <<<<<< Change 2
    }
   });
  alert(this.$el.html() ); // THIS ONE WORKS FINE
}