box_tpv1 = {
box:$("#box_tpv1"),
open:function(mensaje,f_ok,f_x){
this.box.show()
}
}
And when I call this box_tpv1.open() won't work, but If I write inside open function $("#box_tpv1").show() it works.
In your case, box_tpv1 is a singleton object, which cannot be further instantiated using new. Which means the value of this is insignificant.
You might as well simply call box_tpv1.box.show() inside the open function.
there might be issues on the context this function is being called and that depends upon from where are you calling this function from
try calling like this
box_tpv1.open.call(box_tpv1);
I don't know why but I solved it this way, I can get with this.box the value inside the object methods but doesnt work the jquery selector, if I do that it works
box_tpv1 = {
box:"#box_tpv1",
open:function(mensaje,f_ok,f_x){
$(this.box).show()
}
}
Related
Using ES6/ES2015 and webpack, I am trying to wrap my head around the little monster that is the keyword this.
I have a class Edit containing a static method change(event) and within that method I am trying to make a recursive call to the method itself (depending on a given variable).
In most cases I could just call this.change(event) but here the keyword this is already occupied by the jquery object that was calling the function instead of the containing class.
The easiest solution would be to just call Edit.change(event) instead, but there must be a cleaner solution. Every programming language I have encountered so far has had some reference to its containing class built in.
I promise I have checked the docs and other threads on stackoverflow, but no one I found seems to address this particular problem.
// main.js
'use strict';
const $ = require('jquery');
const Edit = require('./Edit');
$(document).ready(() => {
let thingsToAddToData = {
whatToDo: // defined here depending on context
someVariable: //defined here depending on context
};
$('table :input').change(thingsToAddToData, Edit.change);
}
and here the Edit class is defined
// Edit.js
class Edit {
static change(event) {
if(event.data.whatToDo === 'do_nothing'){
return false;
}
if(event.data.whatToDo === 'do_this_important_thing'){
// here some important stuff is done
return true;
}
if(event.data.someVariable === 'special_case'){
event.data.whatToDo = 'do_this_important_thing'
// THIS IS THE LINE THAT GIVES ME HEADACHES
return this.change(event);
}
// here some default stuff is done
}
}
module.exports = Edit;
The easiest solution would be to just call Edit.change(event) instead, but there must be a cleaner solution
No, this is indeed what you need to use to always refer to the Edit class. There's nothing messy with it, just use it.
You could also use this.change(event) if you weren't using the method as an event handler. Make sure to call it as a method:
$('table :input').change(thingsToAddToData, Edit.change.bind(Edit));
// or
$('table :input').change(thingsToAddToData, e => Edit.change(e));
Either of the answers by #Bergi, should work (using Function.prototype.bind or () => {}). However I think your problem is more structural. Since Edit.change is an event handler it doesn't make sense to call it directly, since it is supposed to be fired through events.
I would suggest firing the event again with some parameter changes (http://api.jquery.com/trigger/):
replace Edit.change(event); with this.trigger(event);
That way there is no need for calling the handler directly, and you don't need to change the this context, thus keeping the code more transparent.
Static methods operate on the class instead of instances of the class, they are called on the class. There are two ways to call static methods:
<ClassName>.methodName()
or
<class-instance>.constructor.methodName()
In static methods, the this keyword references the class. You can call a static method from another static method within the same class with this.
I am trying to create a basic javascript framework that you can pass different things into, including functions for it to execute later. Right now, I'm in a more simple testing phase, but I can't quite get the function calling to work. A piece of my code is here:
[My JS Fiddle][1]http://jsfiddle.net/mp243wm6/
My code has an object that holds different data, and I want to call the method later, but with data that is available at the time of creation. Here is a code snippet of the function that uses the function that is passed to the object:
clickMe : function() {
this.obj.click(function() {
this.func();
});
}
Any suggestions or things I should read are welcome.
The problem is that there're two different contexts:
clickMe : function() {
// here is one
this.obj.click(function() {
// here is another
this.func();
});
}
You can simple pass the function as parameter, like the following:
clickMe : function() {
this.obj.click($.proxy(this.func, this));
}
http://jsfiddle.net/mp243wm6/2/
The problem:
Considering your code in the JSFiddle, you have:
onClick : function() {
this.obj.click(function() {
this.func();
});
},
As noted, you have different contexts going on here.
Consider the snippet this.obj.click(function() { this.func(); }). The first this here is a reference to the framework.events object. The second this here is a reference to whatever will be this when this function get called. In the case of your JSFiddle, when this.func gets called, this is actually the DOM object that represents the <div id="test">TEST</div> node. Since it doesn't have a func function, calling func() on it causes:
Uncaught TypeError: undefined is not a function
You have to understand the following: you have to pass the correct this in which you want the function func to be called.
The solution:
A couple of ways to make it work as you would like:
1. with bind
this.obj.click(this.func.bind(this));
This way, you are telling: "call my this.func function, but make sure that it will be called using the this that I am passing as a parameter". Vanilla JS, no $.proxy stuff.
JSFiddle
2. with a copy of the reference to the actual function
onClick : function() {
var theFunctionReference = this.func;
this.obj.click(function() {
theFunctionReference();
});
},
This way, you will not rely on the value of this outside of the context of the framework.events object.
JSFiddle
The issue is that this is not bound to the correct object. I would suggest you look into Function.bind() because that creates a function with this pointing to the right thing.
I am using backboneJS model.on ('change:attribute',functionName(someParameter)) to listen to change in model's attribute and call a funcion with given parameter. But the problem I am facing is the function is being called initially even when there is no change in the model. After that,even when the model changes, the function is not called. I did some trials and found out that without the parameter, if I called ('change:attribute',functionName),
the events fired properly. I can not understand what the problem is. Can anyone help as I think I am missing something very basic here. And a way to approach such problem would be much appreciated. Thanks.
The .on() method expects you to pass the callback function or method that will be called to handle the event. But in your first example you tried to pass a result of that callback.
So inside it will execute yourCallback.call(...) or yourCallback.apply(...). Obviously it could not execute the .call() method of non-function value.
But you can wrap the method call in anonymous function though if you really need it. For example if you need to use that someParameter value:
var MyView = Backbone.View.extend({
// ...
myMethod: function(someParameter) {
this.model.on('change:attribute', function() {
functionName(someParameter);
});
}
});
I have gotten JSONP working with an anonymous function but can't get it to work with a named function. This code works (the alert appears with the correct data):
$.getJSON('http://example.com/test.aspx?foo=bar&callback=?',
function (data) { alert(data.baz) })
However this code does not work (no alert appears):
function dat(data) {
alert(data.baz)
}
$.getJSON('http://example.com/test.aspx?foo=bar&callback=dat')
Can you explain why the last code does not work?
EDIT: I took out a non-relevant example
I'm not sure that leaving out the callback is the correct usage (or, at least, I cannot find any documentation that defines what should happen if a callback is not supplied). If you want to use a named function as the callback you can do:
function dat(data) {
alert(data.baz)
}
$.getJSON('http://example.com/test.aspx?foo=bar&callback=?', dat);
You should be able to meet jQuery half way with something like this:
$.getJSON('http://example.com/test.aspx?foo=bar&callback=?', dat);
After looking at jquery's ajax code a bit, I think what you want to do is either
do like Dave Ward and Hamish suggest, ie pass in the function. Or, I think you can pass the function's name as a string like this, since it is attached to the window and jquery looks at the type of the callback for determining behavior.
function dat(data) {
alert(data.baz)
}
$.getJSON('http://example.com/test.aspx?foo=bar&callback=?', 'dat');
Or, you can use getScript which will add the url as a script tag, which is fine for what you are trying to do.
function dat(data) {
alert(data.baz)
}
$.getScript('http://example.com/test.aspx?foo=bar&callback=dat');
I have an onclick handler for an <a> element (actually, it's a jQuery-created handler, but that's not important). It looks like this:
function handleOnClick() {
if(confirm("Are you sure?")) {
return handleOnClickConfirmed();
}
return false;
}
From this function, the this object is accessable as the <a> element clicked. However, handleOnClickConfirmed's this is a Window element! I want handleOnClickConfirmed to have the same this as handleOnClick does. How would I do this?
(I know I can pass this as an argument to handleOnClickConfirmed, but some of my code already uses handleOnClickConfirmed and I don't want to have to rewrite those calls. Besides, I think using this looks cleaner.)
The following ought to do it:
function handleOnClick() {
if( confirm( "Sure?" ) ) {
return handleOnClickConfirmed.call( this );
}
return false;
}
The call() function attached to Function objects is designed to allow this; calling a function with a desired context. It's an extremely useful trick when setting up event handlers that call back into functions within other objects.
Rob's answer is the best answer for your problem, but I wanted to address something that you wrote in your original question:
I know I can pass this as an argument to handleOnClickConfirmed, but some of my code already uses handleOnClickConfirmed and I don't want to have to rewrite those calls.
JavaScript parameters are always optional, as far as the interpreter is concerned. For example if you have the function:
function MyFunction(paramA, paraB) {
// do nothing
}
All of these calls will execute without error:
MyFunction(1,2);
MyFunction(1);
MyFunction();
So you could modify handleOnClickConfirmed to accept what would essentially be an optional parameter. Like so:
function handleOnClickConfirmed(context) {
context = context || this;
// use context instead of 'this' through the rest of your code
}
Again, in this particular case, the call function is the best solution. But the technique I outlined above is a good one to have in your toolbox.