I have the following class in javascript:
function User(aJid){
this.jid = aJid;
this.name = '';
this.uni = '';
this.edad = '';
this.foto = '';
this.avatar = '';
this.initialize2 = function(){
$('#edit_vcards').on('click', '#enviar_vcard', function(){
//alert("enviando...");
console.log(this);
});
};
As you can see I have a method "initialize2" that binds a function to some elements in the DOM. In there I do a console.log(this) which prints the DOM element we binded the method to and not the object that is executing the method initialize2. How can I have access to that object from that function?
Its like if the scope of the function binded is the whole DOM and not the object. Anyway to do what Im trying to do ?
function User(aJid){
this.jid = aJid;
this.name = '';
this.uni = '';
this.edad = '';
this.foto = '';
this.avatar = '';
this.initialize2 = function(){
var that = this; //store a reference to maintain scope
$('#edit_vcards').on('click', '#enviar_vcard', function(){
//alert("enviando...");
console.log(that); //use that variable here
});
};
Try passing the obj this to .on and the inside the handler you can use event.data to access the obj this. See below,
this.initialize2 = function(){
$('#edit_vcards').on('click', '#enviar_vcard', {obj_this: this }, function(){
//alert("enviando...");
console.log(event.data.obj_this); //should be the obj this
});
};
Pass the outer this through event.data:
$('#edit_vcards').on('click', { outerThis: this }, function (event) {
console.log(event.data.outerThis);
});
Nowadays with ES6 it can be even more elegant
$('#edit_vcards').click( () => {
//alert("enviando...");
console.log(this); // all your variables are availabled here
});
or even like that (if you need only one line):
$('#edit_vcards').click( () => console.log(this) );
NOTE: This code cannot be used directly and should be additionally compiled with balel, for example.
Related
So i need to get the inner text of a given element through a Jquery event, and then set this text into a member of my class e.g.
myClass = function ()
{
this.index = 0;
this.onNavElementClick = function ()
{
this.index = parseInt(this.text());
}
this.myMain = function ()
{
$("nav#wow-so-much-inspiration").on("click", "a", this.onNavElementClick);
}
}
myObject = new myClass();
myObject.myMain();
HTML:
<nav id="wow-so-much-inspiration">
1
2
3
</nav>
But this won't work because of the two different scopes inside the onNavElementClick() function... And i don't like the idea of doing _this = this, i'm pretty sure there is a right way to do that without doing MacGyver coding.
jQuery event handlers also take the event object (including the target on which the event was triggered) as a first argument. Then you can use $.proxy to have your event handler bound to the outer this.
Something like this:
this.onNavElementClick = $.proxy(function (e)
{
this.index = parseInt($(e.target).text());
}, this);
You could make use of the bind method, but I believe this has been proven to have minor performance implications.
Example - which is essentially what the $.proxy answer does.
var myClass = function ()
{
this.index = 0;
this.onNavElementClick = (function (event) {
this.index = parseInt( $(event.target).text() );
}).bind(this);
this.myMain = function ()
{
$("nav#wow-so-much-inspiration").on("click", "a", this.onNavElementClick);
};
}
var myObject = new myClass();
myObject.myMain();
Another option is to use call or apply with a simple wrapper function.
var myClass = function ()
{
this.index = 0;
this.onNavElementClick = function (event)
{
this.index = parseInt( $(event.target).text() );
};
this.myMain = function ()
{
var self = this;
$("nav#wow-so-much-inspiration").on("click", "a", function (event) {
self.onNavElementClick.call(self, event);
});
};
}
var myObject = new myClass();
myObject.myMain();
Define onNavElementClick as a var within the my class constructor and reuse the function as needed.
var onNavElementClick = function(){...};
I need to call the object showMe() method from a child object, when debugging the this does not recognize the showMe() method.
How can I reference an object method from within the method ???
code follows -
function myObj(n) {
this.name = n;
this.frame = $('<div />');
var subFrame = $('<div />');
subFrame.on("click", function () {
**//how do I reference this.showName() from here ?**
});
this.frame.append(subFrame);
this.showName = function (nn) {
alert(nn);
};
}
$(function () {
var a = new myObj("Test");
});
A common way to do this is to define var that = this, and refer to that in the function body.
You could also use bind, but then you give up the local scope.
You can actually just pass a reference to the object into on() as data,
function myObj(n) {
this.name = n;
this.frame = $('<div />');
var subFrame = $('<div />');
subFrame.on("click", {myObj : this}, function (e) {
e.data.myObj.showName();
});
this.frame.append(subFrame);
this.showName = function (nn) {
alert(nn);
};
}
$(function () {
var a = new myObj("Test");
});
FIDDLE
I'm creating the script files for my Project using Object Orientation and I also use frameworks/widgets like jQuery and Datatables.
The public properties I create on my class, are not accessible from the inner scope of functions that are executed from jQuery code.
Here is a sample:
function MyClass() {
this.MyProperty = '';
}
MyClass.prototype.initialize = function() {
$(document).ready(function(){
alert(this.MyProperty); // MyProperty is undefined at this point
}
};
How can I fix this? Is this the correct way to have a property that can be accessed from every member of a class?
store this :
function MyClass() {
this.MyProperty = '';
}
MyClass.prototype.initialize = function() {
var that=this;
$(document).ready(function(){
// in event handler regardless of jquery this points
// on element which fire event. here this === document,
alert(that.MyProperty); // MyProperty is defined at this point
}
};
That is because this does not point to your class but to the document in that function. You need to store what it points to, when it points to your class:
function MyClass() {
this.MyProperty = '';
}
MyClass.prototype.initialize = function() {
var myClassInstance=this;
$(document).ready(function(){
alert(myClassInstance.MyProperty); // Will contain the property
});
}
$.proxy can help with this,
function MyClass() {
this.MyProperty = '';
}
MyClass.prototype.initialize = function() {
$(document).ready($.proxy(function(){
alert(this.MyProperty);
},this));
};
This is a little different from the others, but a little easier to work with. Keeps the logic of assigning the "this" context outside of the initialize() function itself. Your unique case could nullify this solution from being viable, but thought I'd share anyway.
function MyClass() {
this.MyProperty = '';
$(function(){
this.initialize();
}.call(this));
}
MyClass.prototype.initialize = function () {
alert(this.MyProperty);
}
...
$.fn.annotateEdit = function(image, note) {
if (note) {
this.note = note;
} else {
var newNote = new Object();
newNote.id = "new";
this.note = newNote;
}
}
...
var mynote = this.note;
form.find(':radio').change(function() {
var vacancy = $(this).attr('value');
mynote.vacancy = vacancy;
});
...
Is it possible to access "this.note" from the change() handler without defining "mynote"?
I use a pattern like this so I can access anything in the enclosing scope:
var that = this;
...
form.find(':radio').change(function () {
that.note.vacancy = $(this).attr('value');
});
I am a fan of this pattern because it makes the code a little more readable. In my opinion, it is clear what it being accessed is part of the enclosing scope (as long as the usage of that is consistent).
Use $.proxy to bind it to a function...
// Returns a function-------v
form.find(':radio').change( $.proxy(function() {
var vacancy = $(this).attr('value');
mynote.vacancy = vacancy;
}, this) );
// ^---- ...that has its "this" value set as this argument.
There is no dedicated language mechanism for it. The common pattern is to store the this in local (closure) variable (often named self or that) of the outer function:
var self = this;
var innerFunction = function() {
self.x = 1;
};
Check this - http://api.jquery.com/bind/ and "Passing event data"
You can do something like this :
form.find(':radio').bind("change", {
context : this
}, function(event){
console.log(event.data.context);
console.log(event.data.context.note);
});
You can bind the context of the parent object like so.
form.find(':radio').change(function(that) {
var vacancy = $(this).attr('value');
that.note.vacancy = vacancy;
}.bind(null,this));
I've got a big Javascript project that I'm trying to refactor into pseudo-classes:
jsFiddle: http://jsfiddle.net/waitinforatrain/7T42w/
var MyNameSpace = {}
MyNameSpace.MyClass = function() {
this.doSomething = function () {
return "hello";
}
this.doSomething2 = function() {
var x = this.doSomething() + " world";
alert(x);
}
this.doSomething2(); //Works fine
$("#mydiv").click ( this.doSomething2 ); //Doesn't work
}
var class = new MyNameSpace.MyClass();
The reason the click event causes an error is that this refers to the #mydiv element.
How am I supposed to design the above so that I can access the element that was clicked but can also call doSomething()?
You need to cache the context reference and wrap the call in a closure:
var MyNameSpace = {}
MyNameSpace.MyClass = function() {
var context = this;
context.doSomething = function () {
return "hello";
}
context.doSomething2 = function() {
var x = context.doSomething() + " world";
alert(x);
}
// You can do this:
context.doSomething2();
// Or this:
$("#mydiv").click(function(e) {
context.doSomething2();
});
}
this.doSomething2 = $.proxy(function() {
var x = this.doSomething() + " world";
alert(x);
}, this);
$.proxy binds the this scope to the context variable inside said function.
Save a reference to this in the outer scope:
MyNameSpace.MyClass = function() {
var that = this;
this.doSomething = function () {
return "hello";
}
this.doSomething2 = function() {
var x = that.doSomething() + " world";
alert(x);
}
this.doSomething2(); //Works fine
$("#mydiv").click ( this.doSomething2 ); //Doesn't work
}
The function assigned to doSomething2 is said to "close over" the variables in its lexical scope and so has access to their values even once MyClass has returned. This allows us to access the doSomething method through the reference to the instance we assigned to that.