[英]Dojo AMD not loading custom module
I'm trying to make a web application using the ArcGIS API, Dojo, and Flask. 我正在尝试使用ArcGIS API,Dojo和Flask制作Web应用程序。 I want to start by making a "file uploads" dialog, which I am trying to define as its own module using the Dojo 1.7 AMD convention (ie "define").
我想从创建“文件上传”对话框开始,我试图使用Dojo 1.7 AMD约定(即“定义”)将其定义为自己的模块。
Here is my file structure: 这是我的文件结构:
\static
home.js
fileUpload.js
\templates
home.html
main.py
Here is the code for the dialog (copied from one of the Dojo Tutorials). 这是对话框的代码(从《 Dojo教程》之一复制)。 I am basically trying to put all dialog related function (ie show and hide) in one module:
我基本上是试图将所有与对话框相关的功能(即显示和隐藏)放在一个模块中:
define([ "dijit/registry", "dijit/Dialog", "dijit/form/Button", "dojo/ready", "dojo/domReady!" ], function (registry) { console.log("HELLO WORLD"); return { // Show the dialog showDialog: function() { registry.byId("uploads").show(); }, // Hide the dialog hideDialog: function() { registry.byId("uploads").hide(); } } });
At the end of "home.js" I try to create and instance of the dialog module: 在“ home.js”的结尾,我尝试创建对话框模块的实例:
var fu = new fileUpload();
Then in my "home.html" file, I define the actual dialog and try to use the "fu" object's variables as event handlers for closing and opening the dialog: 然后在我的“ home.html”文件中,定义实际的对话框,并尝试使用“ fu”对象的变量作为事件处理程序来关闭和打开对话框:
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <meta name="viewport" content="initial-scale=1, maximum-scale=1, user-scalable=no"> <title>morPOP</title> <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-beta/css/bootstrap.min.css" integrity="sha384-/Y6pD6FV/Vv2HJnA6t+vslU6fwYXjCFtcEpHbNJ0lyAFsXTsjBbfaDjzALeQsN6M" crossorigin="anonymous"> <link rel="stylesheet" href="https://js.arcgis.com/4.5/esri/css/main.css"> <link rel="stylesheet" href="../static/css/home.css"> <script src="https://js.arcgis.com/4.5/"></script> <script src="../static/js/home.js"></script> </head> <body> <!-- Map --> <div id="viewDiv"></div> <!-- Upload Button --> <div class="btn-toolbar" role="toolbar" aria-label="Toolbar with button groups"> <button type="button" id="uploadbtn" class="btn btn-primary" onclick="fu.showDialog()">Upload</button> </div> <!-- Upload Dialog --> <div class ="dijitHidden"> <div id="uploads" data-dojo-type="dijit/Dialog" data-dojo-props="title:'Upload Files'"> <p>The following files must be uploaded to run a simulation. File names must match those listed below.</p> <p>Acceptable file extensions: .txt or .csv</p> <ul> <li>Geographic data</li> <ul> <li>Age_Dissemination</li> </ul> <li> Probability Data </li> <ul> <li>ageContactDuration_hospital_nurse</li> <li>ageContactDuration_hospitalPatient</li> <li>ageContactNumber_hospital</li> </ul> <li> ??? </li> <ul> <li>Census_Division_Mapping</li> </ul> </ul> <button onclick="fu.hideDialog();">Finish</button> </div> </div> </body> </html>
The error that I get in the google Chrome developer console is the following: 我在Google Chrome开发者控制台中收到的错误如下:
Uncaught TypeError: Cannot read property 'on' of undefined
at new g (init.js:56)
at home.js:51
at Q (init.js:18)
at init.js:18
at A (init.js:18)
at ea (init.js:18)
at d (init.js:20)
at HTMLScriptElement.<anonymous> (init.js:23)
I'm not sure what "on" property the error is referring to. 我不确定错误所指的是“ on”属性。 Does anyone have any ideas?
有人有什么想法吗? Why can't I declare an instance of my module?
为什么不能声明模块的实例?
** EDIT *** **编辑***
I've changed my home.js file to "require" fileUpload.js, but I am now getting the following error when I try to click the "submit" button: 我已经将home.js文件更改为“ require” fileUpload.js,但是当我尝试单击“提交”按钮时,出现以下错误:
(index):24 Uncaught ReferenceError: fu is not defined
at HTMLButtonElement.onclick ((index):24)
Please see the following plunkr for my updated home.js file: https://plnkr.co/edit/9dFVHsFOCji1aE0ZeLRQ?p=preview 请为我更新的home.js文件查看以下plunkr: https ://plnkr.co/edit/9dFVHsFOCji1aE0ZeLRQ ? p = preview
When using AMD you manage your dependencies by defining things as you have done with define()
but client of module must import it using require()
function, see docs , meanwhile you try to instantiate required module via new
which is not correct. 使用AMD时,您可以通过定义事情来定义依赖项,就像使用
define()
但是模块的客户端必须使用require()
函数导入它, 请参阅docs ,同时尝试通过不正确的new
实例化所需的模块。
To use some module in DOM handler you need extra wrapper eg your HTML would make onclick="whenClicked()"
if you have this function in scope: 要在DOM处理程序中使用某些模块,您需要额外的包装器,例如,如果您在范围内具有此功能,则HTML将使
onclick="whenClicked()"
可能:
function whenClicked() {
require(['fileUpload'], function(fu) {
fu.showDialog();
});
}
assuming of course that 'fileUpload' is correctly specified AMD module. 当然,假设“ fileUpload”是正确指定的AMD模块。
EDIT: modified version of OP sample on Plunker: https://plnkr.co/edit/QFckwndDicGpTfzhGwFC?p=preview 编辑: Plunker上OP示例的修改版本: https ://plnkr.co/edit/QFckwndDicGpTfzhGwFC ? p = preview
Note fileUpload.js
module definition changed so that basic alert is displayed: 注意
fileUpload.js
模块定义已更改,以便显示基本警报:
define([
"dijit/registry",
"dijit/Dialog",
"dijit/form/Button",
"dojo/domReady!"
], function (registry) {
return {
// Show the dialog
showDialog: function() {
//registry.byId("uploads").show();
alert("this is file upload mock");
}
}
});
as well as home.js
hosting definition of whenClicked
: 以及
home.js
托管的定义whenClicked
:
function whenClicked() {
require({
packages: [
{name: "fileUpload",
// location should point to fileUpload.js on your target server
location: "https://run.plnkr.co/uv2ILkhQpQC2wqRV",
main: "fileUpload"}
]},
['fileUpload'], function(fu) {
console.log("fileupload");
fu.showDialog();
});
}
Note that showing location
of module is similar to what bRIMOs said in other answer. 请注意,显示模块的
location
与bRIMO在其他答案中所说的相似。 My approach configures however location only for this particular code wrapped by require; 但是,我的方法仅针对由require包裹的特定代码配置位置。 approach of bRIMOs is global.
bRIMO的方法是全球性的。
Be aware however that Plunker is rebuilding location
URL each time you reload editor :/ it effectively means tha you fix location prefix, run it fine, reload Plunker page, and it is broken again. 但是请注意,每次您重新加载编辑器时,Plunker都会重新构建
location
URL://这实际上意味着您修复了位置前缀,可以很好地运行它,重新加载Plunker页面,然后它再次被破坏。
I think you missed to configure the path in dojo config in order to access the fileupload.js file by the AMD loader , In the dojoConfig doc there is many type of config ( basURl ,package , paths ...) , below you can see how to make configuration using packges
, and dojo will load you files using require without any problem 我认为您错过了在dojo config中配置路径以便通过AMD加载程序访问fileupload.js文件的方法。dojoConfig文档中有许多类型的配置(basURl,package,path ...),下面您可以看到如何使用
packges
进行配置,并且dojo将使用require加载文件而不会出现任何问题
So before loading your arcgis js api <script src="url_api_js"></script>
be sur to do the folowing (configuring dojo with dojoConfig
var) 因此,在加载arcgis js api
<script src="url_api_js"></script>
之前, dojoConfig
进行以下操作(使用dojoConfig
var配置dojo)
<script type="text/javascript">
var dojoConfig = {
packages: [
{
name: "mypackage",
location: location.pathname.replace(/[^\/]+$/, '') +"/static"
}
]
};
<script>
<script src="url_api_js"></script>
and the inside your code use the name of package/name of file as below 并且代码内部使用包名称/文件名称,如下所示
require(['mypackage/fileUpload'], function(upload) {
upload.showDialog();
});
NB: the location could change , according to the server type , in this exemple the location is like : {location_name}/static/fileupload.js
注意:根据服务器类型,位置可能会更改,在此示例中,位置类似于:
{location_name}/static/fileupload.js
hopefully this would help you . 希望这对你有帮助。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.