简体   繁体   English

Dojo AMD不加载自定义模块

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM