0

我一直试图让某人向我解释 dojo AMD 加载的工作原理,并让一段简单的代码工作。我知道如果使用例如 CDN,则必须调用 dojo 库并加载您希望使用的所有模块。我尝试根据主页上的活动来实现其他 javascript 函数,但我总是会得到未定义的函数或与未定义的 dojo 控件相关的错误。似乎最初加载的所有模块都不适用于其余代码。任何有用的解释将不胜感激。

          <link rel="stylesheet" type=
        "text/css" href="http://ajax.googleapis.com/ajax/libs/dojo/1.8.4/dojo/resources
                           /dojo.css" />
          <link rel="stylesheet" type=
        "text/css" href="http://ajax.googleapis.com/ajax/libs/dojo/1.8.4/dijit/themes/
                           tundra/tundra.css" />
          <link rel="stylesheet" type=
        "text/css" href="http://ajax.googleapis.com/ajax/libs/dojo/1.8.4/dojox/mobile/themes/
                           iphone/iphone.css" />
         <title> DOJO </title>
         <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/dojo/1.8.4/
                   dojo/dojo.js" 
              data-dojo-config="async:true"></script> 

      <script type="text/javascript" src="Scripts/login.js"></script>
     <script type="text/javascript">
      require(["dojox/mobile/parser",
                "dojo/parser",
                "dojo/on",
                "dojo/request/xhr",
                "dijit/form/Form",
                "dojo/store/Observable",
                "dojo/store/Memory",
                "dijit/Toolbar",
                "dijit/Dialog",
                "dojo/io/script",
                "dojo/query",
                "dojo/_base/lang",
                "dijit/layout/ContentPane",
                "dojox/mobile/Button",
                "dojox/mobile/deviceTheme",
                "dojox/mobile/compat",
                "dojox/mobile/Heading",
                "dojox/mobile/TextBox",
                "dojox/mobile/Opener",
                "dijit/form/TextBox",
                "dijit/form/HorizontalSlider",
                "dijit/form/ValidationTextBox",
                "dijit/Calendar",
                "dojox/mobile/ScrollableView",
                "dojo/dom",
                "dojo/domReady!",
                "dojox/mobile"],

        function (dom, domReady ,mobile, ScrollableView, 
               parser, query, domClass, domStyle, on, event, xhr,Form,
             lang, Button, deviceTheme, compat, Heading) {
            dojox.mobile.parser.parse();
        });

</script> 

据我了解,我拥有上面代码的方式是我的界面将正确加载,并且 html 正文中的所有小部件都将显示并且工作正常。问题是我有一个从用户那里获取输入的表单,并且在按钮单击事件上调用一个处理 webrequests 的函数。我无法让它工作,这只是我放置此功能的位置的问题。我添加了一个简化版本:

我所做的是将该函数添加到脚本文件中,以将其与其余代码分开:

var dojoXhr;

function correctInput(div, td, msg) {
dojo.domStyle.set(div, 'display', '');
td.innerHTML = msg;
}

require(["dojo/_base/declare", "dojo/parser", "dojo/query", "dojo/dom-class", 
     "dojo/dom-style",   "dojo/on", 
     "dojo/_base/event",
     "dojo/request/xhr", "dijit/form/ValidationTextBox", "dojo/domReady!"], 
  function chklogin(declare, parser, query, dom-class, dom-style, 
      on, event, xhr,ValidationTextBox, domReady) {

   var lname = dijit.byId('login').get('value');
   var psswd = dijit.byId('password').get('value');
   var feedback = document.getElementById('feedback');
   var feedbackTD = dojo.query('td.feedback')[0];
   if (lname == '' || psswd == '') {
       correctInput(feedback, feedbackTD, 'Please enter a valid login!');
       dojo.domStyle.set(feedback, 'display', '');
       dojo.domStyle.set(document.getElementById('msgBodyOutter'), 'display', 'none');
       feedbackTD.innerHTML = "Please enter a valid login!";
       return;
   }
   if (!(lname == 'login') || !(psswd == 'password')) {
       correctInput(feedback, feedbackTD, 'Please enter a valid login!');
       return;
   }
   else {
       dojo.domStyle.set(feedback, 'display', '');
       dojo.domStyle.set(document.getElementById('msgBodyOutter'), 'display', 'none');
       feedbackTD.innerHTML = "THATS IT BRO!";
       return;
   }


});

我在 dojo 论坛上得到了建议,将我的函数放在定义函数中,然后使用 require 来调用它。我不知道该怎么做。

4

1 回答 1

3

似乎最初加载的所有模块都不适用于其余代码。

您正在使用CDN加载 dojo 工具包。当您使用 CDN 时,您需要定义模块包的位置。您需要编辑 dojoConfig 才能使代码正常工作。

请参阅这篇关于将自定义模块与 CDN 结合使用的文章。重要的部分是包对象。

<script data-dojo-config="async: 1, dojoBlankHtmlUrl: '/blank.html',
        packages: [ {
            name: 'custom',
            location: location.pathname.replace(/\/[^/]+$/, '') + '/js/custom'
        } ]"
    src="//ajax.googleapis.com/ajax/libs/dojo/1.9.1/dojo/dojo.js">
</script>

编辑:下面是一个简单的 dojo 应用程序。

因此,在我的例子中,创建一个名为 chklogin 的模块,然后 require 它,当用户单击按钮时,它将从主 require[] 函数中调用该模块 chklogin。正确的?

我会说是的。你是对的。我认为你的概念是一个可行的选择。我希望这个例子有助于实现 define() 来创建你自己的模块。当你发展你的想法时,我会尽我所能提供帮助。您可以在可用时在此处下载该项目。

目录结构:

/index.html
/js/config.js
/js/controller/Controller.js
/js/modules/MyFirstModule.js

/index.html

<!doctype html>
<html>
    <head>
    <meta charset="UTF-8">
     <title>Demo</title>
    <link rel="stylesheet" href="http://ajax.googleapis.com/ajax/libs/dojo/1.9.1/dijit/themes/claro/claro.css">
    <script src="js/config.js"></script>
    <script src="http://ajax.googleapis.com/ajax/libs/dojo/1.9.1/dojo/dojo.js"></script>
    <script>
        require(["app/Controller", "dojo/domReady!"], function(Controller) {

            //Initiate the entire application by calling main method of our Controller class. 
            Controller.main();

            //Call our getter method of the Controller class to show how to access a private variable.
            console.log(Controller.getWelcomeMessage());
        });
    </script>
    </head>

    <body class="claro" id="appBody"></body>
</html>

/js/config.js

我们使用来引用CDN dojo 文件。现在我们可以通过我们的包名来调用 dojo 类,例如"dojo/domReady!", "dijit/form/Button", "dojox/app/main"。dojo 文件存储在 google 服务器上,由 <script src='http://ajax.googleapis.com/ajax/libs/dojo/1.9.1/dojo/dojo.js'>< /script> index.html 文件中的 引用。

在这里,我们创建自己的自定义包。这可能适用于您的模块、小部件等。包位置将映射到您存储自定义 dojo 文件的 javascript 目录。例如,可以在该目录中找到myModules 。/js/modules您将通过 引用任何自定义 dojo 文件"myModules/MyModule",它会定位并加载"/myModules/MyModule.js"文件。

有关 的解释baseURL,请参阅:http ://dojotoolkit.org/documentation/tutorials/1.9/hello_dojo/ “定义和要求模块”。此代码注册了我们自己的包的正确位置,因此我们可以从 CDN 加载 Dojo,同时仍然能够加载本地模块。

我创建了一个包"app",如下所示。这就是我在项目中初始化应用程序的方式。这是为了让我能够尽我所知地保持代码分离。它在 index.html 页面中加载和调用。所以我给它一个app的包名。它物理上位于 js/controller/Controller.js文件中。

此 dojoConfig 对象在 index.html 中使用,并且必须在标记之前加载< script src='...dojo.js' >

var dojoConfig = {
    async: true,
    tlmSiblingOfDojo: false,
    baseUrl: location.pathname.replace(/\/[^/]*$/, ''),
    packages: [
        { name: "myModules", location: "js/modules" },
        { name: "app", location: "js/controller", main: "Controller" }
    ]
};

如果您选择在您自己的服务器上托管 dojo 文件,您可以像下面这样引用它们。假设dojo js 文件位于"/js/dojo/*"目录中。

packages: [
        { name: "dojo", location: "dojo/dojo" }, 
        { name: "dijit", location: "dojo/dijit" },
        { name: "dojox", location: "dojo/dojox" },
        { name: "myModules", location: "js/modules" },
        { name: "app", location: "js/controller", main: "Controller" }
    ]

/js/controller/Controller.js

这是我用来初始化 Web 应用程序的控制器。

define(["myModules/MyFirstModule"], function(MyFirstModule) {

    //Private Variables...
    var privateVariable1 = "Welcome to my Dojo Application!";
    var privateVariable2;

    /**
     * init. This is a private function that is only available within this object.
     */
    init = function() {
        // proceed directly with startup
        console.log("Startup functions are firing...");

        //Render our "form" which only contains a single text box.
        renderForm();
    },

    renderForm = function() {
        MyFirstModule.createForm("appBody");
    }

    /**
     * Enclose all public methods in the return object
     */
    return {

        /**
         * main. This is a public function that can be called from other code.
         */
        main: function() {

            //Run init() method.
            init();
        },

        /**
         * getWelcomeMessage. This public function returns the value of the privateVariable1.
         * This mimics a getter method.
         */
        getWelcomeMessage: function() {
            return privateVariable1;
        }
    };

}); //end define

/js/modules/MyFirstModule.js

这是自定义模块的示例。Controller 类需要它作为依赖项。

define([
    //The required dependencies for this module.
    "dojo/dom", "dojo/on", "dijit/form/TextBox", "dijit/form/Button"
], function(dom, on, TextBox, Button){
    // Once all modules in the dependency list have loaded, this
    // function is called to define the myModules/myFirstModule module.
    //
    // The dojo/dom module is passed as the first argument to this
    // function; additional modules in the dependency list would be
    // passed in as subsequent arguments (on, TextBox, and Button).

    // Private variables
    var firstNameTextBox;
    var submitButton;

    privateFunction = function() {
        console.log("I am a private function. I can only be called from this class.");
    };

    // This returned object becomes the defined value of this module when called elsewhere.
    return {
        /**
         * createForm. This method creates a simple form. Textbox and button.
         * @param placeMeHere This is where to place the form elements. In this demo, the are placed in the 
         * body of the html document. This is executed in the Controller class.
         */
        createForm: function(placeMeHere) {

            //Create new TextBox.
            firstNameTextBox = new TextBox({
                name: "firstname",
                value: "" /* no or empty value! */,
                placeHolder: "type in your name"
            }, "firstname");

            //Place me in the DOM.
            firstNameTextBox.placeAt(placeMeHere);

            //Render 
            firstNameTextBox.startup();

            //Create Button
            submitButton = new Button({
                label: "Say Hi"
            }, "submitButton");
            submitButton.placeAt(placeMeHere);
            submitButton.startup();

            //Greet the user.
            on(submitButton, "click", function(evt){
                console.log("Hi there, " + firstNameTextBox.get("value"));
            });

        }
    };
});
于 2013-12-03T22:27:05.267 回答