#14742 closed defect (fixed)
_WidgetsInTemplateMixin problematic with concurrent Dojo versions?
Reported by: | fredfortier | Owned by: | bill |
---|---|---|---|
Priority: | undecided | Milestone: | 1.8 |
Component: | Dijit | Version: | 1.7.1 |
Keywords: | Cc: | ||
Blocked By: | Blocking: |
Description
Background: I am trying to refactor an application to take advantage of Dojo 1.7.1. I am using async mode with AMD syntax. Sadly, my application widgets do not fully run standalone but in one of IBM's iWidget platform (Business Space V7 if it matters to anyone). So I need to work with two concurrent version of Dojo: 1.3.2 (IBM build for the BS stuff) and my custom namespaced 1.7.1 build.
Problem statement: I was able to create my custom Dojo build using custom packages name and run it together with IBM's build successfully (see details below) -- EXCEPT for one thing. IBM's Dojo becomes angry whenever I require "dijit/_WidgetsInTemplateMixin" in my code. I can create templated widgets fine as long as I set the Dijits programatically, but I can't get the app to parse the Dijit declared in the template without affect the Dojo 1.3.2 instance.
Symptoms: Here is my djConfig. I am setting insertAbsMids: 0 when generating my custom Dojo 1.7.1 build.
dojoConfig = { has : { "dojo-firebug" : true, "dojo-debug-messages" : true }, async : 1, parseOnLoad : true, baseUrl : '/lcsdojo/js/dojo-release-1.7.1-LCS/dojo/', packages : [ { name : 'lcsDojo', location : '/lcsdojo/js/dojo-release-1.7.1-LCS/dojo', packageMap : { dojo : 'lcsDojo', dijit : 'lcsDijit', dojox : 'lcsDojox' } }, { name : 'lcsDijit', location : '/lcsdojo/js/dojo-release-1.7.1-LCS/dijit', packageMap : { dojo : 'lcsDojo' } }, { name : 'lcsDojox', location : '/lcsdojo/js/dojo-release-1.7.1-LCS/dojox', packageMap : { dojo : 'lcsDojo', dijit : 'lcsDijit', dojox : 'lcsDojox' } }, { name : 'iWidget', location : '/CustomWidgets/catalog/com/td/dms/widgets/iWidget' }], deps : ['lcsDojo'], callback : function() { logGlobals(); require(['lcsDojo/domReady!'], function() { console.info("lcsDojo DOM Ready!"); }); } };
Here is how I define and declare my custom widget. As pointed out, this code works fine if I do not use the _WidgetsInTemplateMixin "feature" (programatic syntax only).
define("iWidget/viewer/viewerWidget", [ "lcsDojo/_base/declare", "lcsDijit/_WidgetBase", "lcsDijit/_TemplatedMixin", "lcsDijit/_WidgetsInTemplateMixin", //<-----Code his works until I add this "lcsDojo/text!/CustomWidgets/catalog/com/td/dms/widgets/iWidget/viewer/templates/viewerView.html", "iWidget/util/Util", "lcsDijit/layout/BorderContainer", "lcsDijit/layout/ContentPane" ], function(declare, _WidgetBase, _TemplatedMixin, _WidgetsInTemplateMixin, template) { declare("iWidget.viewer.viewerWidget", [_WidgetBase, _TemplatedMixin, _WidgetsInTemplateMixin], { templateString : template, workplaceGetContentUrl : null, ...
Here is what IBM Dojo 1.3.2 has to say about this from the FireBug? console output. It's Dijit object does not seem to be able to read its own registry anymore. I suspect that the Dijit registry is some sort of global variable without a different namespace in this case. NOTE: dojo.js in this case is the 1.3.2 version, not the custom namespaced 1.7.1.
dojo.byId is not a function (?)()59 (line 257) (?)()60 (line 940) log()dojo.js (line 16) [Break On This Error] undefineddojo._scopeArgs = [undefined];
I looked at the source of dijit/_WidgetsInTemplateMixin.js. The snippet below caught my attention.
Could the scope: "dojo" line be the issue? Should this be scoped based on the Dojo package name?
_beforeFillContent: function(){ if(this.widgetsInTemplate){ // Before copying over content, instantiate widgets in template var node = this.domNode; var cw = (this._startupWidgets = parser.parse(node, { noStart: !this._earlyTemplatedStartup, template: true, inherited: {dir: this.dir, lang: this.lang, textDir: this.textDir}, propsThis: this, // so data-dojo-props of widgets in the template can reference "this" to refer to me scope: "dojo" // even in multi-version mode templates use dojoType/data-dojo-type })); this._supportingWidgets = registry.findWidgets(node); this._attachTemplateNodes(cw, function(n,p){ return n[p]; }); } },
Change History (9)
comment:1 Changed 9 years ago by
comment:2 Changed 9 years ago by
also, try adding an entry for dijit: 'lcsDijit'
to the lcsDijit packageMap. it may not be effective but i've found it to be necessary in the past - which is not to say that its still necessary now but its simple enough for you to try.
ben...
comment:3 Changed 9 years ago by
@neonstalwart - yes, that was the issue. Pretty simple indeed. I am now able to import _WidgetsInTemplateMixin from my Dojo 1.7 package without impacting Dojo 1.3.2.
comment:4 Changed 9 years ago by
Milestone: | tbd → 1.8 |
---|---|
Owner: | set to bill |
Status: | new → assigned |
Great, thanks @neonstalwart.
I see in _WidgetsInTemplateMixin.js and a few other files that we have absolute MIDs instead of relative ones. I'll fix that.
comment:5 Changed 9 years ago by
ah... that would be why it's needed. i'd figured it would have to be something like that but never took the time to figure out why i needed the extra configuration when my understanding was that in theory it shouldn't have been needed (unless there were explicit references to dijit).
i think i also noticed a few places that have dependencies of just "." and those should probably be changed to "./main" to be safe.
comment:6 Changed 9 years ago by
OK, I'll fix dojo/ and dijit/.
dojox/ has a lot of errors and an increasing number of svn:external packages, so those updates will need to be left to the individual package owners.
comment:8 Changed 9 years ago by
bill you missed a reference to dojo in dojo/robot but besides that, i think its better to export to dijit/main rather than using setObject. using setObject seems to imply that you mean to make something global whereas exporting to dijit/main would just seem to imply that you want to augment that single module (which might not necessarily be global if you config the loader appropriately). it may turn out that if you config the loader to not expose globals that setObject and augmenting dijit/main are still the same but i think by using dijit/main the intention is clearer. as you say, in 2.0 it all goes away so then it doesn't matter - i don't think dijit/main makes much sense in 2.0
Hmm, mysterious. I don't understand what's going on either although the error about:
That must be from bootstrap.js in dojo version 1.3, which does:
I don't see the connection to the _WidgetsInTemplateMixin.js or to the parser though.
I think the "scope" parameter is OK; it just means that the parser from your dojo 1.7 instance will search for data-dojo-type/dojoType inside templates, rather than whatever you redefined scope too, for example data-dojo17-type/dojo17Type.
When _WidgetsInTemplateMixin calls the parser, I'd like to make sure that it's going to the 1.7 parser rather than the 1.3 parser. Can you trace that through firebug (or just with console.log() statements)? I guess your lcsDijit packageMap should handle that, but might as well confirm it.
You said you are working with two versions of dojo, but how about parsing the main document? Is the main document being parsed, and if so, are you running the parser from one version of dojo, or the other version, or trying to split parsing between the two versions? Are you setting parseOnLoad: true?