After a few days away, I tackled the problem a little more in-depth today. It is definitely a scoping issue, but the cause of the scoping issue still eludes me. I found a workaround though.
I've found that I can get the DICOM images to load properly from localhost using the WADOImageLoader as expected in a barebones Angular2 + Cornerstone app. Using that same process in our actual app, I found that I was still running into an issue wherein the WADOImageLoader gets all the way to the getImagePromise step of loadImage or loadAndCacheImage call prior to resolving the ImagePromise and can't load because it finds the wadouri scheme properly but has an empty imageLoaders object (i.e. cornerstone.registerImageLoader failed to register the imageLoaders object). Interestingly, removing the cornerstone.registerImageLoader code from the JS closure didn't help resolve the scoping issue with cornerstone.loadImage but removing the cornerstoneWADOImageLoader function loadImage from the closure and using it directly as a global function loaded the image properly.
I think this goes back to the style by which Cornerstone is written being fairly incompatible with the ES6 / Angular2 way of doing things with scoping to a specific module/component being preferred over creating global namespaces or closures. Additionally, really interacting with the DOM directly is kind of frowned upon. The preferred mechanism is to have your own renderer render a component (so you could, for example, render components all in web workers and stitch the rendered components together in the browser or server-side). I understand the reasons why cornerstone does direct DOM manipulation (honestly, I'm not sure any graphics manipulation like cornerstone, d3.js, and similar libraries will be done in that manner without significant rewrites).
Anyway, end result is that I'm going to likely hand-roll an alternative to the cornerstoneWADOImageLoader that works better with Angular2, since the core cornerstone libraries besides the ImageLoaders seem to work fine with Angular2. The big problem is being able to communicate the data from the Angular2 app into the image loader, load the image, and propagate data from cornerstone and DOM events back into Angular2 when it's time to update data in the database.
- Michael