在Dojo中交换AMD模块依赖项

在Dojo中交换AMD模块依赖项,dojo,requirejs,amd,Dojo,Requirejs,Amd,下面是MyWidget.js模块中声明的小部件类 define(["dojo/Foo","myapp/Bar"], function(Foo, Bar) { return declare('MyWidget', [], { postCreate:function() { var bar = new Bar(); bar.sayHello(); } })}); 在这个理论示例中,“myapp/Bar”是一个通过返回declare调用类似地定义的类。现在让我们假

下面是MyWidget.js模块中声明的小部件类

define(["dojo/Foo","myapp/Bar"], function(Foo, Bar) { return declare('MyWidget', [], {
   postCreate:function() {
      var bar = new Bar();
      bar.sayHello();
   }
})});
在这个理论示例中,“myapp/Bar”是一个通过返回declare调用类似地定义的类。现在让我们假设我已经通过扩展“myapp/Bar”创建了“myapp/SpecialBar”

在另一个小部件中,我想告诉MyWidget使用“myapp/SpecialBar”而不是“myapp/Bar”,如下所示:


我知道怎么做。例如,我可以向“myapp/MyWidget”添加一个Bar属性,并分配Bar模块的值。这将允许我这样实例化:
newmywidget({Bar:SpecialBar})
。然而,这似乎太拘谨了。是否有一种干净的方法可以在不对模块定义进行任何特殊处理的情况下交换AMD依赖项?

这是一种干净的方法。您不能更改小部件/模块所依赖的模块,您可以映射它们,但这是全局性的,因此它总是映射到特定的模块

如果你能做到这一点,你也可以打破很多东西,而且,这样的功能在任何语言中都不存在。将
require()
与Java和.NET中的导入进行比较,您将看到类似的趋势

更改模块的唯一方法是更改模块的行为/状态,这意味着重写属性或函数。当模块“可交换”时,通常将其用作属性,例如:

  • dojo/dnd/Moveable
    类允许您通过
    Mover
    属性设置自定义
    dojo/dnd/Mover
    。在这种情况下,构造函数作为属性添加到可移动()中
  • 所有具有下拉菜单的小部件都继承自
    dijit/\u HasDropDown
    ,它将下拉菜单小部件本身作为属性添加到父小部件中

好的。我当时的想法是对的。问题是,我必须预测未来哪个模块可能是“可交换的”。这不是AMD的一个缺陷,还是我看错了?任意更改依赖项绑定通常很有用,特别是对于单元测试。使用这种方法,我不仅需要每个依赖项,而且还必须对将来可能需要不同绑定的依赖项进行特殊处理。我希望能够避免这种复杂性。对于单元测试,您可以映射模块,并在回答中详细解释:
require(["myapp/MyWidget","myapp/SpecialBar"], function(Foo, SpecialBar) { 
   //Now swap "myapp/Bar" module dependency of "myapp/MyWidget" to "myapp/SpecialBar"
   var myWidget = new MyWidget();
});