14. Another Common Stumbling Point
• Resources and Modules
• The magic of dojo.require
• Register Module Path
• Custom modules when using Dojo from a CDN
Friday, September 16, 2011
15. You guys already knew this stuff, but....
• Don’t forget, you are JavaScript Astronauts
• You were loading modules when these
kids were in diapers
• Anticipating where newcomers will struggle
is the most powerful tool of the educator
Friday, September 16, 2011
16. Stage Three: Gem Mining
The Staples® of JavaScript toolkits.
“Dojo: Yeah, we’ve got that.”
Friday, September 16, 2011
17. My favorite gem: Attribute Maps
Bind widget properties to widget DOM Nodes.
Update property, DOM node gets updated automatically.
Friday, September 16, 2011
18. Widget Attribute Maps
<!-- In Widget Template HTML -->
<span data-dojo-attach-point="heroNode"></span>
// Specified as a property on your widget definition
attributeMap: {
hero: {
node: "heroNode",
type: "innerHTML"
}
}
// Calling 'set' on hero updates the innerHTML of 'heroNode'
myWidget.set("hero", "Larry Bird");
Friday, September 16, 2011
19. Widget Attribute Maps
// Also possible to bind to a CSS class or HTML attribute
attributeMap: {
// Bind to a CSS class
prop: {
node: "someNode",
type: "class"
},
// Bind to an HTML attribute
prop2: {
node: "imageNode",
type: "attribute",
attribute: "src"
}
}
Friday, September 16, 2011
20. More Complex Bindings: Custom Setters
Add function to your widget with naming convention:
_setPropertynameAttr
// Whenever widget.set(‘funkiness’, value) is called,
// this function is called
_setFunkinessAttr : function(brandNewFunk) {
// Do what needs to be done to update the widget
// to the new level of funkiness
}
Friday, September 16, 2011
21. One Gotcha...
_Widget has an attributeMap, don’t clobber it.
attributeMap:
dojo.delegate(dijit._Widget.prototype.attributeMap, {
// Attribute Map definition
})
Friday, September 16, 2011
22. Gotcha resolved in Dojo 1.7...
• attributeMap is deprecated, to be removed in Dojo 2.0.
• All property/DOM bindings can be specified via _set
convention. To specify an attributeMap relationship, return
an object instead of a function. Nice.
_setHeroAttr: { node: "heroNode", type: "innerHTML" }
Friday, September 16, 2011
23. Demo Time
Let’s see those Attribute Maps in action.
It’s me. Of course we’ll use a silly widget.
Friday, September 16, 2011
29. Memory Leaks
Historically, not a big deal for web apps.
That time is over.
Friday, September 16, 2011
30. Tony Gentilcore
Web Performance Expert at Google:
Awesome blog post about using
Chrome’s DevTools Heap Profiler:
http://gent.ilcore.com/2011/08/finding-memory-leaks.html
Friday, September 16, 2011
31. Widget Specific Leak
• Widgets within Widgets can leak
• Calling destroyRecursive() on a widget generally
cleans up child widgets
• Child widgets defined declaratively in HTML
template get cleaned up
• Widgets new’d programmatically do not get cleaned up
Friday, September 16, 2011
32. Example Leaky code
dojo.declare("poopin.PhijitTriumvirate")
<!-- Widget Template -->
<div>
<div data-dojo-attach-point="phijits"></div>
</div>
postCreate : function() {
for(var i = 0; i < 3; i++) {
var p = new poopin.Phijit(); // Leaky Phijit
dojo.place(p.domNode, this.phijits, "last");
}
}
Friday, September 16, 2011
33. Should I avoid doing this?
No! This is perfectly natural,
just make sure you clean up after yourself.
Friday, September 16, 2011
34. Clean up - Two techniques
Quick and Dirty:
• Append your programmatically created widgets to
this._supportingWidgets
• Internal, subject to change.
Better:
• Keep track of these widgets yourself, destroy them when
the parent is destroyed.
• http://higginsforpresident.net/2010/01/widgets-within-widgets/
Friday, September 16, 2011
35. Lightweight Leak Detection
dijit.registry to the rescue!
To detect leaks:
• Query the registry
• Perform interactions that should result in net zero widgets
•Query the registry again to produce a diff
Friday, September 16, 2011
36. dijit.registry Query code
// Query the registry
my_widgets = [];
dijit.registry.forEach(function(widget){
my_widgets.push(widget.id);
});
console.log("Widgets Captured (" + dijit.registry.length + ") in total)");
// Query it again, produce a Diff
var leakyWidgets = [];
dijit.registry.forEach(function(widget){
if(dojo.indexOf(my_widgets, widget.id) === -1) {
leakyWidgets.push(widget.declaredClass);
}
});
console.log(leakyWidgets.length + " potential leaks found");
console.log("Potential Leaks: " + leakyWidgets.join(", "));
Friday, September 16, 2011
38. Most Important Stage
• Stage Two: Kicking the Tires
• This is where we lose people
• If you care about Dojo, you should not be OK with this
Friday, September 16, 2011