TJ and David,
Thanks - that was all very useful information and I have things
working now.
The info.key.info.value business was, in retrospect, a fairly silly
failure to think about the order of operations. I somehow expected it
to have been (info.key).(info.value), rather than
((info.key).info).value...
Good to know that Hash only works with string keys. Obvious, I guess,
or at least well documented :)
As a followup, given the working approach:
MyClass1.prototype.observeValueChange = function(observer, property,
callback) {
if (this.observableChanges == null) this.observableChanges = new
Hash();
var observationTuples = this.observableChanges.get(property);
if (observationTuples == null) {
observationTuples = new Array();
this.observableChanges.set(property, observationTuples);
}
var tuple = new Object();
tuple['observer'] = observer;
tuple['callback'] = callback;
observationTuples.push(tuple);
}
MyClass1.prototype.fireValueChanged = function(property) {
if (this.observableChanges == null) return;
var observationTuples = this.observableChanges.get(property);
if (observationTuples == null) return;
var that = this;
observationTuples.each(function(tuple) {
var obj = tuple.observer;
var func = tuple.callback;
func.call(obj, that);
});
}
I have several classes that I'd like to have this functionality. What
approach would you recommend for doing that? Subclassing?
Thanks,
Wil
On Dec 4, 3:38 am, david <[email protected]> wrote:
> Hi,
>
> Thanks to TJ answer, I forgot THE each second argument to
> automatically bind the called function to a context.
>
> --
> david.
>
> On 4 déc, 12:22, "T.J. Crowder" <[email protected]> wrote:
>
>
>
> > Hi,
>
> > > Tracing through the code, everything appears fine up to the point
> > > where I try to call the stored callback. This line:
>
> > > info.key.info.value(this));
>
> > > info.key and info.value are both valid objects, but nothing happens.
>
> > Your 'info.key' property is your observer, which I tend to suspect
> > doesn't then have a property called 'info' on it, but that's what
> > "info.key.info" retrieves. Then you retrieve the 'value' property from
> > that and try to call it ("info.key.info.value(this)"). You're also
> > passing in a 'this' value which refers to the browser window, whereas
> > I suspect you wanted to refer to the observable object.
>
> > I think this is what you meant:
>
> > observerInfo.each(function(info) {
> > info.value.call(info.key, this);
> > }, this);
>
> > ...which will call the callback setting the observer as the context
> > (the 'this' value within the callback) and passing in the observed
> > object -- note that to do that, I had to pass 'this' into #each as its
> > second argument because otherwise context is lost when you call #each.
>
> > But the above, by itself, won't solve the problems because I think you
> > probably have an issue here:
>
> > > this.observableChanges.get(property).set(observer, callback);
>
> > Hash#set is documented as accepting a String for the key, but you're
> > passing in other kinds of objects, not just strings. You can't rely on
> > the key not getting converted to a string (a string that will probably
> > be "[Object]" or similar).
>
> > FWIW, I probably wouldn't use Hash for this at all, it's overkill for
> > the 'observableChanges' property and mis-matched for the values within
> > that. I'd probably just use a plain JavaScript object for
> > 'observableChanges' using the property name as the key, with the value
> > being an array of tuples for the callbacks to make.
>
> > HTH,
> > --
> > T.J. Crowder
> > Independent Software Consultant
> > tj / crowder software / comwww.crowdersoftware.com
>
> > On Dec 3, 9:00 pm, Wil <[email protected]> wrote:
>
> > > Hi all,
>
> > > I'm trying to implement a somewhat generic way for my controller
> > > objects to listen for changes to various properties of my model
> > > objects. I'm not a javascript expert, so there is quite possibly a
> > > Better Way™ of solving the bigger problem - I'm open to pointers in
> > > that direction, if my current approach is not a good idea.
>
> > > Here's the machinery I currently have in place:
>
> > > MyClass.prototype.observeValueChange = function(observer, property,
> > > callback) {
> > > if (this.observableChanges == null) this.observableChanges = new
> > > Hash();
> > > if (this.observableChanges.get(property) == null)
> > > this.observableChanges.set(property, new Hash());
> > > this.observableChanges.get(property).set(observer, callback);
>
> > > }
>
> > > MyClass.prototype.fireValueChanged = function(property) {
> > > if (this.observableChanges == null) return;
> > > var observerInfo = this.observableChanges.get(property);
> > > if (observerInfo == null) return;
> > > observerInfo.each(function(info) {
> > > info.key.info.value(this));
> > > });
>
> > > }
>
> > > Here's an example of registering to listen:
>
> > > objectOfMyObservableClass.observeValueChange(this, 'foo', function
> > > (destination) {
> > > alert("observed change in foo");
>
> > > });
>
> > > objectOfMyObservableClass.fireValueChanged("foo");
>
> > > Tracing through the code, everything appears fine up to the point
> > > where I try to call the stored callback. This line:
>
> > > info.key.info.value(this));
>
> > > info.key and info.value are both valid objects, but nothing happens.
>
> > > Thanks in advance!
--
You received this message because you are subscribed to the Google Groups
"Prototype & script.aculo.us" group.
To post to this group, send email to [email protected].
To unsubscribe from this group, send email to
[email protected].
For more options, visit this group at
http://groups.google.com/group/prototype-scriptaculous?hl=en.