JSFiddle source
I use hello.bind('Hi!!!')
but inside method hello i get view-model Object instead of string value. Any ideas why?
Change your markup to:
<button data-bind="click: hello.bind($data, 'Hi!!!')">Say hello</button>
From the documentation:
Alternatively, if you prefer to avoid the function literal in your view, you can use the bind function, which attaches specific parameter values to a function reference. More on bind can be found at Mozilla.
Related
I noticed people pass $event to listener functions, like this:
<li v-for="entry in entries">
<div #dragenter="doStuff($event, entry)">
...
doStuff(event, entry){...
But is this really necessary? If I don't need to access $event object in the doStuff(), can I just pass my entry variable only? I noticed it works, but I want to know if it's something OK to do, or is $event there for some reason?
You only need to pass $event if you want to deal with the original DOM event
From the Vue.js docs (highlighting added by me):
Sometimes we also need to access the original DOM event in an inline statement handler. You can pass it into a method using the special $event variable:
So, it's not a requirement, but an option. And it can indeed come in handy sometimes. But I normally omit it if I'm not making use of it.
It depends to the use case, sometimes you need to get the event object so you should pass it as a first parameter with that name $event like handle($event [,...]), if you don't need it you could simply pass your other parameters handle([,...]) without that parameter.
You can omit $event if you don't need to know some detail, such as which key is pressed for keyboard event. Also, the order of parameter is not fixed, just match them on both html and js part is okay.
$event in vue event-handlers
...are there to access the eventData that is passed through to the event handler.
E.g.
In native DOM-Events you have several properties on the event object that might be of interest to you (target especially).
In vue-emitted Events you can pass data: $emit('event-name', eventData). Your $event variable will take the value of this eventData.
$event is a special keyword vue uses. It allows you to pass the eventData as well as custom parameters to your event handlers.
Here is the official doku
I currently have an object which I want to pass as a parameter to another function inside a template literal:
var template = `<button onclick="onclick(${object})"></button>`;
However, this makes the parameter become a string value: [object Object] and doesn't pass the parameter. Is there any way to pass this parameter into the function?
Thank you very much in advance.
You are going to need to represent your object as a string. You can do this using JSON.stringify:
var template = `<button onclick="handleClick(${JSON.stringify(obj).split('"').join(""")})"></button>`;
You will need to escape double quotes (which this code does), and single quotes if used for your onclick event (this code doesn't).
onclick="onclick" actually calls window.onclick - meaning that it picks up clicks anywhere. You should use a different name (such as handleClick).
I would suggest refraining from using inline event listeners for reasons like this, and because they can cause issues if you ever need to adopt a content-security-policy.
I'm trying to bind the value of cat to the (click) function parameter and understandably getting an error. Is there a way I can do this without looping a parent element of the <button>?
<button type="button" (click)="UpdateCategoryFilter({{cat}})" *ngFor="let cat of categories">
{{cat}}
</button>
Never combine [...] or (...) with {{...}} either one or the other, but not both at the same time
It should be
(click)="UpdateCategoryFilter(cat)"
{{...}} is also only for string interpolation. Values bound this way will always be strings, while [foo]="someValue" will pass someValue with the original type if foo is a property.
In html, the code you write in between the quotation marks of an event (such as (click)) is a pure typescript/js code, and as you would not write {{cat}} in your typescript code, you shouldn't write it in the place you wrote it.
Imagine that what you just tried to do is replacing the cat with it's code value, and then executing the code UpdateCatagoryFilter(x), where x is cat's value, and you try to use it as a variable name.
The meaning of (event)="..." syntax is: when an event event is emitted, execute the code ....
This is original code:
h1tag= document.getElementById("myHeading");
h1tag.addEventListener("mouseover", ()=>{h1tag.style.backgroundColor="blue"});
After combining:
h1tag= document.getElementById("myHeading").addEventListener("mouseover", ()=>{h1tag.style.backgroundColor="blue"});
What is the reason behind this?
The problem with this line :
h1tag= document.getElementById("myHeading").addEventListener("mouseover", ()=>{h1tag.style.backgroundColor="blue"});
Is that the statement is evaluated from left to right, so the last method that will be called is addEventListener, so in other words you are trying to store the returned result from addEventListener in your h1tag variable while addEventListener doesn't have a return type so it will return undefined.
To expand on the previous answers, the key issue here is that h1tag is not defined (because addEventListener doesn't return a value) and you are trying to change it's properties.
Fortunately, javascript provides a way to access the element that an event is called on, through an argument passed to the event function.
Try running
document.getElementsById("myHeading")
.addEventListener("mouseover", (e)=>{e.target.style.backgroundColor = "blue"})
h1tag is not defined in your second attempt.
document.getElementById("myHeading").addEventListener("mouseover", (e)=>{e.currentTarget.style.backgroundColor="blue"});
if you still want to kep a reference to the element:
(h1tag=document.getElementById("myHeading")).addEventListener("mouseover", (e)=>{e.currentTarget.style.backgroundColor="blue"});
I am creating a few DOM elements dynamically like,
var anchorElement = jQuery('<a />',{text:property.text});
var liElement = jQuery('<li />',{"class":"navlink_"+i,id:"navlink_"+i});
anchorElement.on('click',property.fnctn);
liElement.append(anchorElement);
parentID.append(liElement);
Where property is a JSON object.
property.text is the text that I want to put into anchor element. (Works fine)
I want to attach a click event handler to that anchor element.
The function that needs to be bound to that element is specified in JSON and we can access it like
property.fnctn
The following line should bind the event handler to the anchor element.
anchorElement.on('click',property.fnctn);
This was not working so I tried converting it into string like,
anchorElement.on('click',property.fnctn.toString());
No Success...
When I click on this link, the error is logged in the console
The object has no method 'apply'.
What is the reason...???
I am able to get it working with a slight work around like
anchorElement.attr('onclick',property.fnctn+"()");
Above statement works, but I want to know why .on() API is not working.
Thanks :)
AÐitya.
Update:
Youve said that property.actfn is a string, "paySomeoneClick". It's best not to use strings for event handlers, use functions instead. If you want the function paySomeoneClick, defined in the string, to be called, and if that function is global, you can do this:
anchorElement.on('click',function(event) {
return window[property.fnctn](event);
});
That works because global functions are properties of the global object, which is available via window on browsers, and because of the bracketed notation described below.
If the function is on an object you have a reference to, then:
anchorElement.on('click',function(event) {
return theObject[property.fnctn](event);
});
That works because in JavaScript, you can access properties of objects in two ways: Dotted notation with a literal property name (foo.bar accesses the bar propety on foo) and bracketed notation with a string property name (foo["bar"]). They're equivalent, except of course in the bracketed notation, the string can be the result of an expression, including coming from a property value like property.fnctn.
But I would recommend stepping back and refactoring a bit so you're not passing function names around in strings. Sometimes it's the right answer, but in my experience, not often. :-)
Original answer:
(This assumed that property.fnctn was a function, not a string. But may be of some use to someone...)
The code
anchorElement.on('click',property.fnctn);
will attach the function to the event, but during the call to the function, this will refer to the DOM element, not to your property object.
To get around that, use jQuery's $.proxy:
anchorElement.on('click',$.proxy(property.fnctn, property));
...or ES5's Function#bind:
anchorElement.on('click',property.fnctn.bind(property));
...or a closure:
anchorElement.on('click',function(event) {
return property.fnctn(event);
});
More reading (on my blog):
Mythical methods
You must remember this
Closures are not complicated