This is a nice solution, but it still has disadvantages. For one, components loaded through addComponent will not be generally available until the current script block has exited and the next has begun. What this means is that if we want to write some component ‘A’ which depends on some other component ‘B’, then all of ‘A’ must be placed inside a listener function that checks for the availability of ‘B’ (and what’s with this implementation that doesn’t allow more than one single listener registered for the entire component hierarchy? Something like the ObserverPattern should have been used).
Worse, if ‘A’ depends on both ‘B’, ‘C’ and ‘D’, then the listener function must painfully remember which of these components are ready, and only execute ‘A’ when all of them have been loaded.
Result: very nasty and voluminous dependency management code.
Another problem would be when some of these components are not specific to myAwesomeApp, but of a more general nature. Then it just doesn’t work at all.
Personally I prefer a more general approach. Traces of it can be seen in the ObserverPattern.js linked above. It contains a line reading “Script.require(‘Prototype’);”. Obviously, what this means, is that this “package” (or component if you will) does not work without first loading something referenced as “Prototype”. “Script” (a generic dependency management package) resolves this dependency by looking up the “Prototype” key in an application specific alias table (because the same components are available from different URI’s in different applications), and then immediately makes this dependency available (an option is included for loading in the same manner as above, but rarely used). The result is one line of code per dependency – that doesn’t change even when components are moved around.
This is a nice solution, but it still has disadvantages. For one, components loaded through addComponent will not be generally available until the current script block has exited and the next has begun. What this means is that if we want to write some component ‘A’ which depends on some other component ‘B’, then all of ‘A’ must be placed inside a listener function that checks for the availability of ‘B’ (and what’s with this implementation that doesn’t allow more than one single listener registered for the entire component hierarchy? Something like the ObserverPattern should have been used).
Worse, if ‘A’ depends on both ‘B’, ‘C’ and ‘D’, then the listener function must painfully remember which of these components are ready, and only execute ‘A’ when all of them have been loaded.
Result: very nasty and voluminous dependency management code.
Another problem would be when some of these components are not specific to myAwesomeApp, but of a more general nature. Then it just doesn’t work at all.
Personally I prefer a more general approach. Traces of it can be seen in the ObserverPattern.js linked above. It contains a line reading “Script.require(‘Prototype’);”. Obviously, what this means, is that this “package” (or component if you will) does not work without first loading something referenced as “Prototype”. “Script” (a generic dependency management package) resolves this dependency by looking up the “Prototype” key in an application specific alias table (because the same components are available from different URI’s in different applications), and then immediately makes this dependency available (an option is included for loading in the same manner as above, but rarely used). The result is one line of code per dependency – that doesn’t change even when components are moved around.
Full source code is available.