2010-08-14 37 views
0

我定義這個類:如何從其方法內的回調函數訪問對象屬性?

function GMap(map, marker, geocoder) { 
    this.map = map; 
    this.marker = marker; 
    this.geocoder = geocoder; 

    this.setMarker = function(address) { 
     this.geocoder.geocode({'address' : address}, function(results, status) { 
      map.setCenter(results[0].geometry.location); 
      marker.setPosition(results[0].geometry.location); 
     }); 
    } 
} 

你怎麼能在回調函數訪問GMAP的map和屬性?

非常感謝。

回答

4

Function對象原型有一個「應用」方法,您可以用它來設置函數中的「this」的上下文。檢查任何geocoder.code是,許多圖書館將處理此爲您的API /代碼通過一個額外的參數,即:

this.someObj.someFn(params, callback, scope); 

在someFn,它同樣也會使用回調到這一點:

callback.apply(scope || window, [callbackArg1, callbackArg2]); 

這將使「回調」中的「this」上下文成爲「範圍」,或者如果沒有傳入任何內容,「this」將是該窗口的全局上下文。一些JavaScript庫還提供了一種方法來創建一個回調函數委託,以確保函數始終在期望的範圍內調用,而不管它從哪裏調用。這方面的一個例子是ExtJS's Function.createDelegate

如果您使用的是不提供這種內置的功能庫,那麼你可以創建一個局部變量到回調封閉內引用,即:

this.setMarker = function(address) { 
    var thisGMap = this; 
    this.geocoder.geocode({'address' : address}, function(results, status) { 
     thisGMap.map.setCenter(results[0].geometry.location); 
     thisGMap.marker.setPosition(results[0].geometry.location); 
    }); 
} 
0

我在猜測它的谷歌地圖?你爲什麼要通過地圖和標記?使它們成爲全局變量(即:將var map;放在所有函數的外部),那麼你應該能夠從任何地方訪問它們。

在函數中重用變量名也是一個壞主意。如果您首先將它們傳遞到函數中,那麼它們將變成函數變量,因此在函數中定義地圖,標記和地理編碼器是毫無意義的,因爲您已經可以使用地圖,標記和地理編碼器訪問它們。 :)

+0

我正在傳遞地圖和標記來做依賴注入=>全局變量在「可測試代碼」中是被禁止的。 :) http://www.youtube.com/watch?v=acjvKJiOvXw – Toto 2010-08-14 17:33:40

1

是這是你在找什麼?

function GMap(map, marker, geocoder) { 
    this.map = map; 
    this.marker = marker; 
    this.geocoder = geocoder; 

    var currentGMap = this; // private variable bound to GMap constructor scope 

    this.setMarker = function(address) { 
     this.geocoder.geocode({'address' : address}, function(results, status) { 
      // currentGMap is available (yay closures) 
      currentGMap.map.setCenter(results[0].geometry.location); 
      currentGMap.marker.setPosition(results[0].geometry.location); 
     }); 
    } 
} 

注:地圖和標記也通過一個封閉的約束,但我想你希望能夠您創建GMAP實例之後,更改地圖和標記屬性。

編輯:是的,我看到凱文在他的最後部分看到了這一點。

0

如果您使用的是jQuery,您可以使用一種名爲$.proxy()的方法來更改上下文(將函數的「this」設置爲任何您想要的值)。

this.setMarker = function(address) { 
    this.geocoder.geocode({'address' : address}, $.proxy(function(results, status) { 
     this.map.setCenter(results[0].geometry.location); 
     this.marker.setPosition(results[0].geometry.location); 
    }, this)); 
} 
相關問題