Upload
danielericlee
View
3.918
Download
1
Tags:
Embed Size (px)
DESCRIPTION
'So, you think you know widgets' A talk by Dan Lee at DojoConf 2011 in Washington, DC.
Citation preview
@DanielEricLee
SO,YOU THINK YOU KNOW WIDGETS
Friday, September 16, 2011
DAN LEE
Friday, September 16, 2011
JAVASCRIPT
Friday, September 16, 2011
Friday, September 16, 2011
Stage One: Doubt
Friday, September 16, 2011
Stage Two: Hate
Friday, September 16, 2011
Stage Three: Begrudging Appreciation
Friday, September 16, 2011
Stage Four: Love
Friday, September 16, 2011
FOURSTAGES
OFWIDGET
WIZARDRY
Friday, September 16, 2011
Stage One: Wonder
I never knew JavaScript could be awesome.
--My friend Tom
Friday, September 16, 2011
Stage Two: Kicking the Tires
With great power, comes...people screwing up.
Friday, September 16, 2011
Alpha Mistake: Accidental Static Fields
dojo.declare("test.Widget", [ dijit._Widget, dijit._Templated ],{ templateString : dojo.cache("test", "templates/Widget.html"), objectProperty: { } // Well, there goes your afternoon.
});
Friday, September 16, 2011
Avoiding Accidental Statics
dojo.declare("test.Widget", [ dijit._Widget, dijit._Templated ], { templateString : dojo.cache("test", "templates/Widget.html"), // Initialize to null objectProperty: null, // Instantiate in constructor constructor: function() { this.objectProperty = {}; }});
Friday, September 16, 2011
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
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
Stage Three: Gem Mining
The Staples® of JavaScript toolkits.
“Dojo: Yeah, we’ve got that.”
Friday, September 16, 2011
My favorite gem: Attribute Maps
Bind widget properties to widget DOM Nodes.
Update property, DOM node gets updated automatically.
Friday, September 16, 2011
Widget Attribute Maps
<!-- In Widget Template HTML --><span data-dojo-attach-point="heroNode"></span>
// Specified as a property on your widget definitionattributeMap: { hero: { node: "heroNode", type: "innerHTML" }}
// Calling 'set' on hero updates the innerHTML of 'heroNode'myWidget.set("hero", "Larry Bird");
Friday, September 16, 2011
Widget Attribute Maps
// Also possible to bind to a CSS class or HTML attributeattributeMap: { // 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
More Complex Bindings: Custom Setters
// 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 }
Add function to your widget with naming convention:
_setPropertynameAttr
Friday, September 16, 2011
One Gotcha...
attributeMap: dojo.delegate(dijit._Widget.prototype.attributeMap, { // Attribute Map definition })
_Widget has an attributeMap, don’t clobber it.
Friday, September 16, 2011
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
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
Beware @phiggins
Friday, September 16, 2011
dojo.declare(“poopin.phijit”)
Friday, September 16, 2011
Stay vigilant at DojoConf caughtyapoopin.com
Friday, September 16, 2011
Phijit code: Let’s see a quick demo
attributeMap: { threatLevel: { node: "threatLevelNode", type: "class" }},_setCounterAttr: function(value) { var threatCss = "low"; this.counterNode.innerHTML = value; if(value >= 3 && value <= 4) { threatCss = "elevated"; } else if (value >= 5) { threatCss = "severe"; } this.set('threatLevel', threatCss);}
Friday, September 16, 2011
Stage Four: Craftsmanship
Friday, September 16, 2011
Memory Leaks
Historically, not a big deal for web apps.
That time is over.
Friday, September 16, 2011
Tony Gentilcore
Awesome blog post about using
Chrome’s DevTools Heap Profiler:
http://gent.ilcore.com/2011/08/finding-memory-leaks.html
Web Performance Expert at Google:
Friday, September 16, 2011
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
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
Should I avoid doing this?
No! This is perfectly natural,
just make sure you clean up after yourself.
Friday, September 16, 2011
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
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
dijit.registry Query code
// Query the registrymy_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 Diffvar 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
Bookmarklet Demo
Friday, September 16, 2011
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
This is so awesome
Friday, September 16, 2011
THE END.@DanielEricLee
Friday, September 16, 2011