Reputation: 2272
I have this little class:
var SwitchHider;
SwitchHider = {
inputSelector: 'body.socials input',
_showOrHideClosestSwitch: function(element) {
var socialUrl, swich_wrapper;
socialUrl = $(element).val();
swich_wrapper = $(element).closest('.white-box').find('.switch');
if (socialUrl.length > 0) {
return swich_wrapper.show();
} else {
return swich_wrapper.hide();
}
},
_bindCallbacks: function() {
$(document).on('ready', function() {
return $(self.inputSelector).each(function(index, element) {
return self._showOrHideClosestSwitch(element);
});
});
return $(document).on('change keyup input', self.inputSelector, function() {
return self._showOrHideClosestSwitch(this);
});
},
initialize: function() {
var self;
self = this;
this._bindCallbacks();
}
};
window.SwitchHider = SwitchHider;
$(function() {
SwitchHider.initialize();
});
(it's compiled from this CoffeeScript file, hope it makes sense):
SwitchHider =
inputSelector: 'body.socials input'
_showOrHideClosestSwitch: (element) ->
socialUrl = $(element).val()
swich_wrapper = $(element).closest('.white-box').find('.switch')
if socialUrl.length > 0
swich_wrapper.show()
else
swich_wrapper.hide()
_bindCallbacks: ->
$(document).on 'ready', ->
$(self.inputSelector).each (index, element) ->
self._showOrHideClosestSwitch(element)
$(document).on 'change keyup input', self.inputSelector, ->
self._showOrHideClosestSwitch(@)
initialize: ->
self = this
@_bindCallbacks()
return
# Send to global namespace
window.SwitchHider = SwitchHider
# DOM Ready
$ ->
SwitchHider.initialize()
return
And when event is triggered - it gives this error:
TypeError: self._showOrHideClosestSwitch is not a function
Does anyone see why? It's my first attempt to write classes like that, don't fully understand what I'm doing.
Upvotes: 0
Views: 46
Reputation: 123473
self
is only defined as a local variable under initialize
. It won't be available to other methods.
initialize: function() {
var self;
self = this;
this._bindCallbacks();
}
You'll either have to define a local self
within each method that needs it:
_showOrHideClosestSwitch: (element) ->
self = this
# ...
_bindCallbacks: ->
self = this
# ...
Or, you can use fat arrows to bind each callback to the surrounding context and use this
or @
instead:
_bindCallbacks: ->
$(document).on 'ready', =>
$(@inputSelector).each (index, element) =>
@_showOrHideClosestSwitch(element)
$(document).on 'change keyup input', self.inputSelector, (ev) =>
@_showOrHideClosestSwitch(ev.currentTarget)
In the event handler, the Element
that's normally the context value can still be retrieved via event.currentTarget
.
Upvotes: 1
Reputation: 10074
self
is not in scope. This is begging for a class syntax:
class SwitchHider
@inputSelector: 'body.socials input'
constructor: ->
$(document).on 'ready', =>
$(SwitchHider.inputSelector).each (index, element) =>
@_showOrHideClosestSwitch(element)
$(document).on 'change keyup input', SwitchHider.inputSelector, (e) =>
@_showOrHideClosestSwitch(e.target)
_showOrHideClosestSwitch: (element) ->
socialUrl = $(element).val()
swich_wrapper = $(element).closest('.white-box').find('.switch')
if socialUrl.length > 0
swich_wrapper.show()
else
swich_wrapper.hide()
# Send to global namespace
window.SwitchHider = SwitchHider
# DOM Ready
$ ->
new SwitchHider()
I used the =>
to handle proper scope of this
Upvotes: 1