我是Java的Javascript新手,我不得不直接为我开始最困难的事情......使用异步模块定义模式开发应用程序......
我正在使用平台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
,我不能......有什么办法吗?或者我从一开始就做错了什么?
正如我所说的那样,我对这一切都是新手,而且我变得疯狂,并且在努力使其发挥作用时,我一直在添加和改变事物,以至于我不知道我到底在做什么做...任何建议将不胜感激......
编辑:如果它有用,这是获取Google地图脚本时的响应(从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/vt?lyrs=m@216000000\u0026src=api\u0026hl=es-ES\u0026","http://mt1.googleapis.com/vt?lyrs=m@216000000\u0026src=api\u0026hl=es-ES\u0026"],null,null,null,null,"m@216000000"],[["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/vt?lyrs=h@216000000\u0026src=api\u0026hl=es-ES\u0026","http://mt1.googleapis.com/vt?lyrs=h@216000000\u0026src=api\u0026hl=es-ES\u0026"],null,null,"imgtp=png32\u0026",null,"h@216000000"],[["http://mt0.googleapis.com/vt?lyrs=t@131,r@216000000\u0026src=api\u0026hl=es-ES\u0026","http://mt1.googleapis.com/vt?lyrs=t@131,r@216000000\u0026src=api\u0026hl=es-ES\u0026"],null,null,null,null,"t@131,r@216000000"],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");
})();
答案 0 :(得分:1)
编辑:我查看了脚本,而不是jsonp,所以我修改了我的答案以使用requirejs。
再次编辑:看来这里还有更多的非同步爵士乐。另一个将全局函数绑定到模块范围的编辑。
查看该URL返回的代码,似乎在代码中它进行另一次异步调用以从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()
时,将在对象的上下文中调用该函数。由于我们在self = this
函数调用中声明了一个变量this.createRenderer()
,然后在该函数调用中定义window.drawMap
,我们创建一个闭包,它将自引用存储到{{ 1}}对象。稍后调用MyController
时,关闭范围中可以使用window.drawMap
引用。现在,在self
函数调用中,我们可以访问window.drawMap
。有关详细信息,请参阅How do JavaScript closures work?。
作为替代方案,您可以考虑使用Miller Medeiros的async plugin加载Google Maps api作为您模块的依赖项。这将是一种更清洁的方式。