Dojo v1.9
I am writing some code that progrommatically creates a widget that I need to place into a layout widget. The problem I currently have is that startup is automatically called over aggressively by dojo.
If the layout widget has already started up, then startup is called when placeAt(domNode) is used. This is not desirable, it would be better to have to explicitly call startup.
I say this because with the current situation, startup is called twice, once for when placeAt is called and once for when startup is called manually straight after that by me.
The Dojo docs and related tutorials say that when creating widgets programmatically you should always call startup manually to be sure correct parsing occurs. But the automatic calling of startup is causing some problems, with duplicate actions occuring on startup, I could move these into postCreate, but that is just hiding the problem.
Here is a simple example of the widget creation/startup...
var myWidget = new Widget();
myWidget.placeAt('mainContent');
myWidget.startup();
mainContent is a div within a ContentPane, here is the layout html...
<body class="claro">
<div id="appLayout" data-dojo-type="dijit/layout/BorderContainer" data-dojo-props="design: 'headline'">
<div data-dojo-type="dijit/layout/ContentPane" data-dojo-props="region: 'center'">
<div id="mainContent"></div>
</div>
<div class="edgePanel" data-dojo-type="dijit/layout/ContentPane" data-dojo-props="region: 'top'">Some text here</div>
<div id="leftCol" data-dojo-type="dijit/layout/ContentPane" data-dojo-props="region: 'left'"></div>
</div>
</body>
The code works, its really the issue of startup being called twice that I'm trying to resolve.
UPDATE: WORKAROUND
Suggested checks inside the startup function against the widget private variable _started are at least protecting me from duplication, here is an example of my check.
startup: function(){
if (typeof this._started === "undefined"){
// call inherited and pass on arguments
this.inherited(arguments);
// then do what ever you need here
}
}
Notice I had to use typeof and not a boolean check, even though after startup the value of _started is true. This was because I discovered the variable isn't actually declared until startup has run at least once, something to look out for.
Anyway, this offers me a workaround, but doesn't fix the issue of startup being called more than once by dojo.
startup() is called automatically quite often in Dojo. For example, whenever you call addChild() on a container widget, the child's startup() method is called. Looking at the source of _WidgetBase, placeAt is also one of those instance.
You should call startup() manually when you use something like dom-construct to place a dojo widget directly on a DOM node.
If you want to check if a widget has started already you can check the _started property inside the widget. This is set inside the startup() method.
Automatically startup widget is a good feature, actually you don't need worry about startup being called twice if you follow the standard code for startup method like :
startup : function() {
if (!this._started) {
//your startup code at here
this.inherited(arguments);
this._started = true;
}
},
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With