2015-06-18 20 views
9

我正在实现一个基于OpenLayers3的Web地图客户端,该客户端应该能够连接到多个WMS服务器,请求WMS功能并显示服务器通告的图层。上述如何避免在每个函数上绑定(this)?

var MyMapClient = function(params) { 
    this.wms_sources_ = params.wms_sources; 
    this.wms_capabilities_ = []; 
} 

MyMapClient.prototype.parse_capabilities = function(index) { 
    var capabilities = this.wms_capabilities_[index]; 
    // do something with capabilities 
} 

MyMapClient.prototype.load_wms_capabilities = function() { 
    var parser = new ol.format.WMSCapabilities(); 

    jQuery.each(this.wms_sources_, (function (index, wms_source) { 

     console.log("Parsing " + wms_source.capabilities_url); 

     jQuery.when(jQuery.ajax({ 
      url: wms_source.capabilities_url, 
      type: "GET", 
      crossDomain: true, 
     })).then((function (response, status, jqXHR) { 
      var result = parser.read(response); 
      console.log("Parsed Capabilities, version " + result.version); 
      this.wms_capabilities_[index] = result; 
      return index; 
     }).bind(this)).then(this.parse_capabilities.bind(this)); 

    }).bind(this)); 
}; 

代码工作正常,但我想打电话给其需要访问MyMapClient的实例的“私有”变量的函数每次我都bind(this)。在没有牺牲可读性的情况下,是否有更好的方式来一致地访问实例内部?

回答

7

我会说使用两全其美的,那就是,一个局部变量保持正确的范围,并呼吁bind()在需要的地方:

MyMapClient.prototype.load_wms_capabilities = function() { 
    var parser = new ol.format.WMSCapabilities(), 
     _this = this; 

    jQuery.each(this.wms_sources_, function (index, wms_source) { 
     console.log("Parsing " + wms_source.capabilities_url); 

     jQuery.when(jQuery.ajax({ 
      url: wms_source.capabilities_url, 
      type: "GET", 
      crossDomain: true, 
     })).then(function (response, status, jqXHR) { 
      var result = parser.read(response); 
      console.log("Parsed Capabilities, version " + result.version); 
      _this.wms_capabilities_[index] = result; 
      return index; 
     }).then(
      function() { return _this.parse_capabilities(); } 
      // or else 
      // _this.parse_capabilities.bind(_this) 
      // pick the one you like more 
     ); 
    }); 
}; 
+0

这是行不通的:'this this' parse_capabilities'方法不会绑定到“实例”上下文,而是绑定到jQuery的上下文(因为它是jquery调用'parse_capabilities'。 –

+0

我已经提出了这种方法现在删除) - OP说他意识到这种方法(应该可以将其编辑到问题中),但是如果可能的话,要避免,并且@deceze正确地指出“那对于then(self.parse_capabilities)'完全没有帮助“ –

+0

编辑,现在应该工作,虽然少”美丽“...也许'bind()'会更好。 –

1

你可以在“硬约束”像这样的方法:

function Foo() { 
    this.bar = this.bar.bind(this); 
} 

Foo.prototype.bar = function() { 
    return console.log(this.baz); 
}; 

顺便说一句,这就是CoffeeScript编译这样做时:

class Foo 
    bar: => 
    console.log @baz 

=>操作导致该保存上下文。

+0

我仍然不知道如何与帮助原型上的'parse_capabilities'方法?我认为无论如何,你仍然必须在调用'.then()'时将其绑定。 –

+0

这适用于'parse_capabilities'方法。但它不能应用于内部匿名函数。 –