2013-05-09 31 views
0

我完全不熟悉Java的Javascript,而且我不得不直接開始爲我的最困難的事情...使用異步模塊定義模式開發應用程序...Javascript中的範圍AMD模式

我正在使用平臺Weejot,它提供了一個framework來開發使用AMD pattern的JavaScript網絡應用程序。所有文件here。你可能不知道它,但也許你可以幫助無論如何,如果你知道的AMD模式...

基本上我有一個模塊MyController.js看起來像這樣(注意,大部分的代碼是自動生成的,我只寫註釋行):

define([ 
    "js/util", 
    "framework/Controller" 
], function (
    util, 
    Controller 
){  
    function MyController(environment, connector) { 
    Controller.call(this, environment); 
    this.settings = environment.siteApplication.getSettings(); 
    this.connector = connector;   
    //Variable where I have some value stored 
    this.myVariable = "hello"; 
    }  

    MyController.prototype = Object.create(Controller.prototype); 

    util.extend(MyController.prototype, { 
    //Function to show a map 
    showMap: function (request, render) { 
     //Get google maps script 
     $.getScript("http://maps.googleapis.com/maps/api/js?key=KEY&sensor=false");   
     //Render is a framework object that basically shows the view "map.html" in full page mode 
     render({name: "map", mode: "fullPage"}); 
    }  
    }); 

    return MyController; 
}); 

這並不正常工作,因爲經過的$.getScript(...)行,劇本似乎並沒有被加載,因爲我不能訪問對象google.maps,裏面應該有被創建...

我通過向腳本url添加回調函數使其工作,像這樣:

$.getScript("http://maps.googleapis.com/maps/api/js?key=KEY&sensor=false&callback=drawMap"); 

的問題是,這個回調函數必須是全球功能,所以我增加了以下功能與前一個模塊(就在return語句之前以上):

window.drawMap = function() { 
    var mapOptions = { 
    center: new google.maps.LatLng(-34.397, 150.644);, 
    zoom: 8, 
    mapTypeId: google.maps.MapTypeId.ROADMAP 
    }; 
    var map = new google.maps.Map(document.getElementById("map_canvas"), mapOptions); 
} 

不知何故,我得到了完美的地圖......但是,我的問題是,我需要訪問變量myVariable從函數window.drawMap,我不能......有沒有辦法做到這一點?或者我從一開始就做錯了一切?

正如我所說我對這一切都很陌生,而且我越來越瘋狂,並試圖讓它工作我一直在添加和改變事物,以至於我不知道我是什麼實際上做...任何建議將不勝感激...


編輯:如果它是有用的,這是獲得谷歌地圖腳本時(從Chrome的控制檯複製)響應:

window.google = window.google || {}; 
google.maps = google.maps || {}; 
(function() { 

    function getScript(src) { 
    var s = document.createElement('script'); 

    s.src = src; 
    document.body.appendChild(s); 
    } 

    var modules = google.maps.modules = {}; 
    google.maps.__gjsload__ = function(name, text) { 
    modules[name] = text; 
    }; 

    google.maps.Load = function(apiLoad) { 
    delete google.maps.Load; 
    apiLoad([0.009999999776482582,[[["http://mt0.googleapis.com/[email protected]\u0026src=api\u0026hl=es-ES\u0026","http://mt1.googleapis.com/[email protected]\u0026src=api\u0026hl=es-ES\u0026"],null,null,null,null,"[email protected]"],[["http://khm0.googleapis.com/kh?v=128\u0026hl=es-ES\u0026","http://khm1.googleapis.com/kh?v=128\u0026hl=es-ES\u0026"],null,null,null,1,"128"],[["http://mt0.googleapis.com/[email protected]\u0026src=api\u0026hl=es-ES\u0026","http://mt1.googleapis.com/[email protected]\u0026src=api\u0026hl=es-ES\u0026"],null,null,"imgtp=png32\u0026",null,"[email protected]"],[["http://mt0.googleapis.com/[email protected],[email protected]\u0026src=api\u0026hl=es-ES\u0026","http://mt1.googleapis.com/[email protected],[email protected]\u0026src=api\u0026hl=es-ES\u0026"],null,null,null,null,"[email protected],[email protected]"],null,null,[["http://cbk0.googleapis.com/cbk?","http://cbk1.googleapis.com/cbk?"]],[["http://khm0.googleapis.com/kh?v=75\u0026hl=es-ES\u0026","http://khm1.googleapis.com/kh?v=75\u0026hl=es-ES\u0026"],null,null,null,null,"75"],[["http://mt0.googleapis.com/mapslt?hl=es-ES\u0026","http://mt1.googleapis.com/mapslt?hl=es-ES\u0026"]],[["http://mt0.googleapis.com/mapslt/ft?hl=es-ES\u0026","http://mt1.googleapis.com/mapslt/ft?hl=es-ES\u0026"]],[["http://mt0.googleapis.com/vt?hl=es-ES\u0026","http://mt1.googleapis.com/vt?hl=es-ES\u0026"]],[["http://mt0.googleapis.com/mapslt/loom?hl=es-ES\u0026","http://mt1.googleapis.com/mapslt/loom?hl=es-ES\u0026"]],[["https://mts0.googleapis.com/mapslt?hl=es-ES\u0026","https://mts1.googleapis.com/mapslt?hl=es-ES\u0026"]],[["https://mts0.googleapis.com/mapslt/ft?hl=es-ES\u0026","https://mts1.googleapis.com/mapslt/ft?hl=es-ES\u0026"]]],["es-ES","US",null,0,null,null,"http://maps.gstatic.com/mapfiles/","http://csi.gstatic.com","https://maps.googleapis.com","http://maps.googleapis.com"],["http://maps.gstatic.com/intl/es_es/mapfiles/api-3/12/11","3.12.11"],[2244818506],1.0,null,null,null,null,0,"blabla",null,null,0,"http://khm.googleapis.com/mz?v=128\u0026","AIzaSyAgUZ1LkdjZ9jsRivdSB4cDLmUAOMOMi34","https://earthbuilder.googleapis.com","https://earthbuilder.googleapis.com",null,"http://mt.googleapis.com/vt/icon"], loadScriptTime); 
    }; 
    var loadScriptTime = (new Date).getTime(); 
    getScript("http://maps.gstatic.com/intl/es_es/mapfiles/api-3/12/11/main.js"); 
})(); 

回答

1

編輯:我看了腳本,而不是jsonp,所以我莫迪fied我的答案使用requirejs。

再次編輯:看起來這裏還有更多的異步爵士樂正在進行。另一個將全局函數綁定到模塊範圍的編輯。

看看該網址返回的代碼,看起來在代碼中它使另一個異步調用從api檢索附加數據,然後調用您的回調。我能想到的唯一方法就是在模塊中定義一個全局函數,並使用它來處理來自api調用的返回值。它不漂亮,但它應該工作:

define([ 
    "js/util", 
    "framework/Controller" 
], function (
    util, 
    Controller 
){  
    function MyController(environment, connector) { 
    Controller.call(this, environment); 
    this.settings = environment.siteApplication.getSettings(); 
    this.connector = connector;   
    //Variable where I have some value stored 
    this.myVariable = "hello"; 
    }  

    MyController.prototype = Object.create(Controller.prototype); 

    util.extend(MyController.prototype, { 
    //Function to show a map 
    createRenderer : function(){ 
     var self = this; 
     window.drawMap = function(){ 
      var mapOptions = { 
      center: new google.maps.LatLng(-34.397, 150.644);, 
      zoom: 8, 
      mapTypeId: google.maps.MapTypeId.ROADMAP 
     }; 
     var map = new google.maps.Map(document.getElementById("map_canvas"), mapOptions); 
     // Do stuff with self.myVariable and, render, ect... 
     }; 
    }, 
    showMap: function (request, render) { 
     //Get google maps script 
     this.createRenderer(); 
     $.getScript("http://maps.googleapis.com/maps/api/js?key=KEY&sensor=false&callback=drawMap");      }  
    }); 

    return MyController; 
}); 

說明:

當你調用this.createRenderer(),該函數被調用你的對象的上下文。由於我們在this.createRenderer()函數調用中聲明瞭一個變量self = this,因此在該函數調用中也定義了window.drawMap,我們創建一個閉包,該閉包存儲對MyController對象的自引用。當稍後調用window.drawMap時,self引用在閉包範圍內可用。所以現在,在window.drawMap函數調用中,我們可以訪問self.myVariable。有關更多信息,請參閱How do JavaScript closures work?

作爲替代選擇,您可以考慮使用Miller Medeiros的async plugin將Google Maps API作爲依賴項加載到您的模塊。這將是一個更乾淨的方式來做到這一點。

+0

感謝您的幫助@Ryan,但我不知道爲什麼,在要求(你寫'//做東西與self.myVariable'),我可以訪問'google.maps',但我不能訪問任何'google.maps.Map'或'google.maps.LatLng',這就像api沒有被加載或什麼...我只能使它與全局回調函數... – MikO 2013-05-09 18:26:33

+0

請參閱編輯與嘗試獲取api腳本時的響應... – MikO 2013-05-09 18:36:13

+0

最終編輯,這應該工作 – 2013-05-09 18:45:02