0

Here is a widget class declared in a MyWidget.js module.

define(["dojo/Foo","myapp/Bar"], function(Foo, Bar) { return declare('MyWidget', [], {
   postCreate:function() {
      var bar = new Bar();
      bar.sayHello();
   }
})});

In this theoretical example, "myapp/Bar" is a class defined similarly by returning a declare call. Now let's assume that I have created "myapp/SpecialBar" by extending "myapp/Bar".

In another widget, I want to tell MyWidget to use "myapp/SpecialBar" instead of "myapp/Bar" like so:

require(["myapp/MyWidget","myapp/SpecialBar"], function(Foo, SpecialBar) { 
   //Now swap "myapp/Bar" module dependency of "myapp/MyWidget" to "myapp/SpecialBar"
   var myWidget = new MyWidget();
});

I know ways to do this. For example, I could add a Bar attribute to "myapp/MyWidget" and assign the value of the Bar module. This would allow me to instantiate like this: new MyWidget({ Bar:SpecialBar }). However, this seems like too much ceremony. Is there a clean way to just swap an AMD dependency without any special treatment to the module definition?

Frederic Fortier
  • 750
  • 8
  • 21

1 Answers1

1

That is the clean way. You cannot change the modules that a widget/module depends on, well, you could map them, but that's done globally, so then it always maps to a specific module.

If you could do that, you could break a lot of stuff as well, besides, such a feature does not exist in any language. Comparing require() with imports in Java and .NET, you will see a similar trend.

The only way to change the module, is by changing the behavior/state of the module, which means by overriding properties or functions. When a module is "swappable" it's often used as a property, examples where this occur:

  • The dojo/dnd/Moveable class allows you to set a custom dojo/dnd/Mover through the mover property. In this case the constructor is added as a property to the Moveable (reference guide)
  • All widgets with a dropdown inherit from dijit/_HasDropDown, which adds the dropdown widget itself as a property to the parent widget
g00glen00b
  • 41,995
  • 13
  • 95
  • 133
  • Ok. I had the right idea then. The problem is that I have to predict which module might be "swappable" in the future. Isn't it a flaw of AMD or am I looking at it wrong? Arbitrarily changing dependency binding is generally useful, especially for unit testing. With this method, not only I have require each dependency, but I also have to give a special treatment to those that may require a different binding in the future. I wish that I could avoid this complexity. – Frederic Fortier Aug 12 '14 at 15:09
  • For unit testing you could map the modules, explained more into detail in this answer: http://stackoverflow.com/questions/16324900/how-to-mock-dependencies-in-intern-tests – g00glen00b Aug 12 '14 at 16:35