I create instances of dijit.layout.ContentPane
, dijit.layout.StackContainer
and dijit.layout.BorderContainer
from my JS code.
It seems I have to call the startup()
method of programatically created instances.
However, I'm not sure I have to call it for every widget.
For instance, when I do a 'new my.foo.widget()
', the startup()
is fired automatically.
Thanks for helping me understanding when to call the startup()
method!
startup() is defined in _Widget, and is simply a "part of the lifecycle". It is the last step in the widget lifecycle, and is not required by all widgets. The most common case where it is absolutely required is when programatically creating layout widgets. It is used as a way to prevent redundant calculations when the children need sizing. For example, a BorderContainer.
var bc = new dijit.layout.BorderContainer({
style:"height:200px; width:200px"
});
// can call bc.startup() now, and the BorderContainer will resize
// all children each time a new child is added. Or, we can add all
// our children now, then trigger startup() and do it all at once.
var top = new dijit.layout.ContentPane({
region:"top", style:"height:100px"
}).placeAt(bc);
var mid = new dijit.layout.ContentPane({ region:"center" }).placeAt(bc);
// now BC will do the calculations, rather than in between each
// the above addChild/placeAt calls.
bc.startup();
Startup is automatically called by the parser in the case of parseOnLoad:true or manual execution. The parser delays calling startup() until all found child widgets have been appropriately instantiated.
dijit.Dialog is a strange case. startup() MUST be called on this widget as well.
var dialog = new dijit.Dialog({ title:"Hmm", href:"foo.html" });
dialog.startup();
dialog.show();
Most widgets do NOT require startup called, but in the cases where something inheriting from _Widget does not override the startup member, the call is essentially a no-op setting this._started = true; If you create your own startup() function, you should either call this.inherited(arguments) or simply set the _started trigger manually.
In Dojo 1.4, the lifecycle here has been adjusted slightly. Previously, a widget with widgetsInTemplate:true would call startup() on the child widgets BEFORE the startup() on the parent. In 1.4 the children's startup() will be called AFTER the parent startup(). This behavior is recursive for however many levels of nested widgets with widgetsInTemplate:true are instantiated.
It is always "safe" to call .startup(), though if you "know" (because it is a simple endpoint widget, or your own custom _Widget code) you can omit the call.
Are you sure that it's called automatically or do you have code in your widget that calls it?
It's good practice to call it since it sets _started
to true
which is used by quite a few widgets for determining behavior and/or layout. Most widgets require that you call it (as you've seen).
startup
is heavily used by composite widgets that need to control sub-widgets.
Basically, anything that inherits from dijit._Widget
should call startup after instantiation.
EDITS:
There's an article on SitePen about the dijit lifecycle which discusses startup a bit in the article itself and in the comments. It's over two years old though and I think things have changed.
The O'Reilly dojo book also talks about startup but it says it should be called on containiner widgets. I've had to call it on the grid though so that doesn't make sense either.
It doesn't really hurt anything by calling it (unless you call it before children are added to your widget). I'd say always call it.
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