views:

1046

answers:

3

Unsure if I've phrased this correctly, but in the callback how do I reference the controls property of the base class?

This has been bugging me for some time and I usually work around it, but I'd be grateful if anybody can enlighten me on how I should do this properly.

var base = function() {
    var controls = {};

    return {
     init: function(c) {
      this.controls = c
     },
     foo: function(args) {
      this.init(args.controls);
      $(this.controls.DropDown).change(function() {
       $(this.controls.PlaceHolder).toggle();
      });
     }
    }
};

Much Obliged,

Paul

+1  A: 

You need to leverage closures here.

var base = function() {
var controls = {};

return {
    init: function(c) {
            this.controls = c
    },
    foo: function(args) {
            this.init(args.controls);
            $(this.controls.DropDown).change(function(controls) {
                    return function(){
                        $(controls.PlaceHolder).toggle();
                    }
            }(this.controls));
    }
}

};

Peter Bailey
Beat me for a moment with more elegant solution :D
Damir Zekić
Something peculiar seems to be happening when I use this approach. The click event fires on page load. I think it has to do with the controls parameter in the callback function because when i remove that the click event doesn't automatically fire.
paulie
What click event?
Peter Bailey
+1  A: 

Use the power of closures:

var base = function() {
    var controls = {};

    return {
        init: function(c) {
                this.controls = c
        },
        foo: function(args) {
                var self = this;

                this.init(args.controls);
                $(this.controls.DropDown).change(function() {
                        $(self.controls.PlaceHolder).toggle();
                });
        }
    }
};
Damir Zekić
Awesome, this works perfectly. Thanks to all who answered.
paulie
A: 

Although closures are preferred, you could also use jquery bind to pass an object along:

var base = function() {
    var controls = {};

    return {
        init: function(c) {
            this.controls = c
        },
        foo: function(args) {
      this.init(args.controls);
      $(this.controls.DropDown).bind('change', {controls: this.controls}, function(event) {
       $(event.data.controls.PlaceHolder).toggle();
      });
        }
    }
};
enobrev
I like this approach and I guess if I am using jQuery extensively throughout my code I should make use of the bind method. I may just use closures for a while so that I get used to using it and then once familiar I can use either. Thanks.
paulie