【问题标题】:Dojo require() and AMD (1.7)Dojo require() 和 AMD (1.7)
【发布时间】:2012-02-29 10:58:35
【问题描述】:

我在过渡到 Dojo 和新的 AMD 结构时遇到了麻烦,我真的希望有人能对整个概念有所了解。过去几周我一直在谷歌上生活,试图找到关于使用的信息,而不是关于使用它的结构和设计模式趋势的信息。

我觉得奇怪的是,对于一个相对复杂的 javascript 应用程序,例如需要创建 Dijit 并设置样式、创建 DOM 元素等的主页,我需要并因此使用 TON 不同的在 AMD 系统之前的 dojo 命名空间中可用的模块(或者,至少没有分配给 23 个不同的变量)。

例子:

require(['dijit/form/ValidationTextBox', 'dijit/form/SimpleTextarea', 'dijit/form/CheckBox', 'dijit/Dialog', 'dijit/form/Form'])
require(['dojo/ready', 'dojo/parser', 'dojo/dom-style', 'dijit/registry', 'dojo/dom', 'dojo/_base/connect', 'dojo/dom-construct'], 
function(ready, parser, style, registry, dom, event, construct){
    //...etc
}

这只是我正在处理的其中一个页面的几个模块。肯定有更好的、不会在未来发布的方式来访问这些方法等。我的意思是,我真的必须导入一个全新的模块才能使用byId()吗?还有另一个连接事件?最重要的是,由于必须在函数参数列表中分配一个变量名来依附而造成的所有混乱似乎都是一种退步。

我想你可能只在需要时才 require() 模块,例如 query 模块,但如果我多次需要它,那么分配给它的变量很可能超出范围,我' d 需要将其放入domReady!ready 调用中。 真的....??!

这就是为什么我只能假设是我对道场缺乏了解。

我确实已经查看、搜索和购买了书籍(尽管是 AMD 之前的书籍),但这个图书馆真的让我为我的钱而奔波。我很感激任何人都可以对此有所了解。

编辑示例

require(['dijit/form/ValidationTextBox'])
require(['dojo/ready', 'dojo/parser', 'dojo/dom-style', 'dijit/registry', 'dojo/dom', 'dojo/_base/connect', 'dojo/dom-construct'], function(ready, parser, style, registry, dom, event, construct){
    /* perform some tasks */
    var _name = new dijit.form.ValidationTextBox({
        propercase : true,
        tooltipPosition : ['above', 'after']
    }, 'name')

    /*
    Let's say I want to use the query module in some places, i.e. here.
    */
    require(['dojo/query', 'dojo/dom-attr'], function(query, attr){
        query('#list li').forEach(function(li){
            // do something with these
        })
    })
}

基于这种格式,它与来自 d​​ojo 工具包人员和第三方站点的许多示例一起使用,恕我直言,加载所有必需的模块是绝对荒谬的,因为第一个 function(ready, parser, style, registy... 会得到越来越长,并产生命名冲突等问题。

启动并require()ing 所有我在脚本生命周期中需要的模块对我来说似乎很愚蠢。话虽如此,我不得不看一些“包管理器”脚本。但是对于这个例子,如果我想在选择的地方使用查询模块,我要么必须在主要的require() 语句中加载它和其余部分。我在一定程度上理解为什么,但是通用点语法命名空间有什么不好? dojo.whatever? dijit.findIt()?为什么要加载模块,以唯一的名称引用,通过闭包,等等等等?

我希望这是一个更容易提出的问题,但我希望这是有道理的。

恼怒

叫我新手,但这真的..真的..让我发疯。当谈到 Javascript(显然不是)时,我不是菜鸟,但哇。我无法弄清楚这个

这就是我要收集的内容。在 adder.js 中:

define('adder', function(require, exports){
    exports.addTen = function(x){
        return x + 10
    }
})

在某些母版页或其他任何内容中:

require(['./js/cg/adder.js'])

...它不遵循整洁的require(['cg/adder']) 格式,但无论如何。现在不重要。

那么,adder的用法应该是:

console.log(adder.addTen(100)) // 110

我得到的最接近的是console.log(adder) 返回3。是的。 3。否则为adder is not defined

为什么要这么难?我正在使用我的菜鸟卡,因为我真的不知道为什么它不在一起。

谢谢大家。

【问题讨论】:

  • 您应该提出一个新问题以进行跟进。您在这里没有足够的代码来向我们展示问题(例如,您甚至没有定义 adder)。
  • 根据您上面的示例,您只需要两个模块依赖项,dijit/form/ValidationTextBox 和 dojo/query,在单个 require 语句中。传递依赖关系为您处理。正如@Domenic 所说,也许这里还有更多内容,我们应该重新开始。
  • 我不是?嗯,是的,我会重新开始。多谢你们。干杯
  • 只需阅读您编辑的问题。至少从您提供的示例来看,大多数依赖是完全没有必要的。您将“需要”ValidationTextBox,最好将引用传回给它,而不是在代码中使用全局 dijit.form.ValidationTextBox 样式引用,并且将为您获取 ValidationTextBox 所需的所有其他内容,因为加载程序处理递归依赖。有道理?其实你写代码的方式,你可能有时间问题,既然你需要ValidationTextBox,那么在另一个语句的回调中使用它。

标签: javascript data-structures dojo js-amd


【解决方案1】:

依赖数组格式:

define(["a", "b", "c"], function (a, b, c) {
});

确实很烦人且容易出错。将数组条目与函数参数匹配是一件很痛苦的事情。

我更喜欢require 格式("Simplified CommonJS Wrapper"):

define(function (require) {
    var a = require("a");
    var b = require("b");
    var c = require("c");
});

这使您的行保持简短,并允许您重新排列/删除/添加行,而无需记住在两个地方进行更改。

后一种格式不适用于 PS3 和较旧的 Opera 移动浏览器,但希望你不在乎。


至于为什么这样做而不是手动命名空间对象,@peller 的回答很好地概述了为什么模块化是一件好事,my answer to a similar question 谈到了为什么 AMD 和模块系统作为实现模块化的一种方式是一件好事.

我要添加到@peller 的答案中的唯一一件事是扩展“关注依赖关系实际上会产生更好的代码”。如果您的模块需要太多其他模块,这是一个不好的迹象!我们在 72K LOC JavaScript 代码库中有一个宽松的规则,即一个模块应该有大约 100 行长,并且需要零到四个依赖项。这对我们很有帮助。

【讨论】:

  • 另一个有趣的事实 - 对于 AMD,当您的模块不再被引用时,您所依赖的代码实际上可以被垃圾收集。当所有内容都附加到全局时,就不会发生这种情况。
  • 另外,请注意 Dojo 的加载器是异步的(使用异步 I/O),所以虽然它支持“立即”CJS 要求签名 @Dominic 在这里显示,但此变体将失败 如果其他一些代码尚未加载该模块。这就是为什么需要一个带有数组和回调的签名。与 AMD 依赖数组格式一样笨拙,它旨在简化异步加载模块的任务。 CJS 主要是为服务器端系统设计的,它没有与 Web 浏览器相同的限制。
  • @peller 错误。 Dojo 和其他兼容 AMD 的加载器将使用 Function.prototype.toString 解析出工厂函数的主体,然后组装一个依赖数组。
  • @peller 这是 RequireJS 中的负责代码:github.com/jrburke/requirejs/blob/master/require.js#L1701-1722 这是在 Noble Modules(实现 CommonJS Modules/2.0,也是异步的)中:github.com/NobleJS/Noble-Modules/blob/…
  • 我只是想为 Dojo 做出断言。 Dojo 会这样做吗?我知道 CJS 如何搜索该函数,但我的意思是建议 AMD 专门设计其 API 来避免这种情况,考虑到不同的、更明确的方法。最后,requirejs 显然做出了妥协。这是 AMD 规范的一部分吗?
【解决方案2】:

requirejs.org 很好地概述了 AMD 是什么以及为什么要使用它。是的,Dojo 正在向您单独引用的更小的模块发展。结果是您加载的代码更少,并且您对它的引用是明确的。我认为,关注依赖关系实际上会产生更好的代码。 AMD 启用优化,一旦迁移完成,您不必再将所有内容加载到全局变量中。没有更多的碰撞! require() 块包装了使用各种模块的代码。 domReady!与 DOM 的加载有关,与范围内的变量无关。

无论如何,这与 SO 的问答形式有所不同。您可能想问一些具体的问题。

【讨论】:

  • 感谢您的信息。我将更多地了解 requirejs 并继续破解它。 编辑原件
猜你喜欢
  • 1970-01-01
  • 2012-04-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-10-10
相关资源
最近更新 更多