Control initialize "this" context messed up?
In QuickUI 0.9.4, I can't get the following code to work anymore:
class window.Demo extends Control
initialize: ->
@someProp = 100
doStuff: ->
@someProp
Demo.create().doStuff #returns undefined
If I set someProp from any other function it works. The same code was working in a previous version of QuickUI. It seems like "this" in the initialize function is something completely different from elsewhere.
I'm using CoffeeScript 1.6.2. Any advice?
I think there are two things going on here.
First, it's generally fragile to stash property values directly on a control instance. If you reacquire a reference to the control by other means, e.g., demo = $('.Demo').control, all the property values will be missing. A stronger solution, and the recommended QuickUI best practice, is to use Control.property to associate values with the underlying DOM element:
class window.Demo extends Control
initialize: ->
@someProp 100
doStuff: ->
@someProp()
someProp: Control.property()
Demo.create().doStuff() # Returns 100
The Control.property() creates a function that gets/sets a property value. The underlying implementation of that uses jQuery's $.data function, which associates data with DOM elements. In this way, the control values will always be consistent no matter how access to the control is obtained. The tutorial page at http://quickui.org/tutorial/control-property-helper.html talks a bit more about this.
Second, even though the above is best practice, I'd still like to understand what broke. Do you happen to know in which QuickUI release your above Demo class worked as you expected? I've tried going back a few releases, but I can't get that Demo class to work in any recent build.
Hmm, okay. I think maybe the documentation should emphasize a little more that you won't necessarily have the same instance for the lifetime of a control. When I first learned about .control() I was wondering why my properties were missing.
I'm not sure which release had my initialize code working since it's in a project I haven't touched in a while and I was just including http://quickui.org/release/quickui.js. Sometime around Dec 2012 / Jan '13. I was just messing around with the generated source before you replied and I got things working by changing initialize(this, $control) to initialize(this, $controls) in Control.createAt. I'm sure that breaks other cases though.
What's the reason for storing the individual properties in jQuery data attributes rather than storing the control itself in a data attribute and using regular properties on that instance? It seems more intuitive to me and it would allow the use of regular properties + "private" properties.
Thanks for the quick response!