After introducing dojo.reload in my previous post, I talked with kriszyp in IRC, and he asked whether
dojo.reload can actually modify already created objects from
dojo.declare-d classes: in most web 2.0 apps, after the app is loaded, there are lots of instances of classes already created, and using
dojo.reload to reload their definition won’t actually update any of these existing instances.
As I do not have an idea to actually implement that, I do come up with another “workaround” (if you like): rather than propagate changes to existing objects on the page, we can actually try to ask the app to reload itself without reloading the whole page. We don’t want to add in any special code in any frontend apps to handle this sort of “self reload” mechanism just to speed up development. Instead, a generic way should be available without any extra logic support in the application layer.
With the help of dojo and with one assumption, I did come up such an implementation to support that. The one assumption is that, all existing objects you care about in your applications are all dijits. If this assumption can be met, what we really need to do in order to reload an application is to:
- call onunload handlers (in case any are registered with dojo)
- destroy all dijits in the page
- reset the
document.body.innerHTML to what it looks like when the page is first loaded (before any js actually modifys it)
- call all onload hanlders registered with dojo (such as dojo.parser etc.)
Item 3 can be achieved via a xhr call to retrieve current page from server and figure out the content within <body> tag. Item 4 requires a bit of extra work, because once all the onload handlers are called by dojo, they are removed. So in order to actually rerun them, we have to remember the original list of handlers.
Of course, as you may already figured, the method mentioned above won’t be able to run any modified onload handlers (even after they are
dojo.reload-ed), however, it does cover most of other cases.
The one assumption mentioned above is not actually true in most web 2.0 applications using dojo, in such cases, any non-dijit objects have to be destroyed somehow so that they can be recreated, but that logic has to be application specific. On the other hand, in order to prevent memory leaks in browsers (espcially IE), it is always a good idea to have a destroy function for your objects to clean itself up. So if you are not worried about any thing other than dijits, then the method mentioned above should work reasonably well, while if you do want to re-create other non-dijits stuffs, you can call some application specific cleanup routines (which as I mentioned above would be good to have in any case).
You can find the code in dojoc.util.loader, the function is actually called
dojo.reloadPage(). The normal use case for this is:
dojo.reload any modules you modified and want to test;
dojo.reloadPage to actually test them without waiting for reloading all js files/reloading your browser window.
dojo.reloadPage only works if it is included in the initial page load, if you
dojo.require dojoc.util.loader after the page is loaded, dojo.reloadPage won’t work (see comment at the beginning of the file to know why)
dojo.reload now also resides in
dojoc.util.loader, and compared to the previous version, two additional features are add:
- Partial module name match: now you just need to type in a partial name of the module you want to reload, if it only matches one module already loaded, that module will be reloaded. If there are multiple matches, it will list all possible modules and error out.
- Automatically remove cache of dijit template: if a module references widget template files (using templatePath), these cached templates will be cleared automatically, so next time you create such a dijit, the new template will be loaded from your sever directly.
A new function to reload css files is also included in
dojoc.util.loader, dojo.reloadCss, which also supports partial name match. If it is given no argument, it will reload all css files in the page (with a href attribute, of course), similar to ReCSS feature in the firebug lite shipped with dojo core.
Warning: use at your own risk.