jQuery event handler queue - jquery-plugins

Overview of the problem
In jQuery, the order in which you bind a handler is the order in which they will be executed if you are binding to the same element.
For example:
$('#div1').bind('click',function(){
// code runs first
});
$('#div1').bind('click',function(){
// code runs second
});
But what if I want the 2nd bound code to run first?
.
My current solution
Currently, my solution is to modify the event queue:
$.data(domElement, 'events')['click'].unshift({
type : 'click',
guid : null,
namespace : "",
data : undefined,
handler: function() {
// code
}
});
.
Question
Is there anything potentially wrong with my solution?
Can I safely use null as a value for the guid?
Thanks in advance.
.

There's an interesting plugin called eventstack. It lets you bind events to either the top or the bottom of the event queue. I don't know how general your problem is, or whether you're looking to reverse or to arbitrarily order events in your stack, but the plugin may simplify your task.
If you're looking to assemble your queue in a very specific order, you can try the approach suggested in this answer -- building custom events that can trigger each other in turn.
Your approach may be the best for your requirement, but perhaps these are options as well.

Related

How to overwrite global event handler in nested Vue component, and later use the previous one?

I am working in Vue and also i use VueRouter, VueX and VueWebsocket. My App has component called App which holds all other components inside itself. Also I have websocket event which is set globally like this:
this.$options.sockets.onmessage = (websocket) => { /* sth1 */ }
When it gets any data from websocket, sth1 is called. it works like charm. However deep inside App component is another component, let's call it InputComponent. It may be included in App or not becaue it is single page aplication and some parts do include InputComponent, and some do not. Inside InputComponent there is also:
this.$options.sockets.onmessage = (websocket) => { /* sth2 */ }
And of course it overwrites function on message so sth1 will never be executed if InputComponent is nested by App component. It is quite obvious. However if i remove (in next SPA page), and InputComponent disappears i still have my onmessage event overwritten which i would like to have in original version.
I could ofcourse make some kind of merging functionalities of sth1 and sth2 in App component or InputComponent but it is repeating myself.
Here comes the question - is there a way to return original version of onmessage event without reloading whole App Component? In other words: can i have temporary overwritten function and then come back to its functionalities? Something like extending an eent with new functionalities of sth2.
I hope you get the idea!
K.
The general way to do that would be to use addEventListener and removeEventListener. So in the input component
created() {
this.$options.sockets.addEventListener('message', handleMessage);
},
destroyed() {
this.$options.sockets.removeEventListener('message', handleMessage);
}
Note that this approach doesn't prevent the original handler from also receiving the events. Without knowing more about the app architecture, it's hard to suggest the best way to avoid this behavior, but perhaps you can set a messageHandled flag on the event in the component's handler; then check that flag in the parent.

ParseReact: Observe queries depending on other queries?

This is more a question of practices than an issue (though I suppose it's an issue in that I don't know if this is possible) with the Parse-React library, but I have a special case where I need to make a query based off of info I get from another query. Ideally I want to do this in the same component. Is this possible?
e.g. the way I have my project setup right now using only Parse and React libraries (not Parse-React) is:
var QueryOne = new ParseQuery("QueryOne");
QueryOne.find({
success: function(results) {
var listOfThingsToGetFromQueryTwo = results.attributes.listOfThingsToGetFromQueryTwo;
var QueryTwo = new ParseQuery("QueryTwo").containedIn("id", listOfThingsToGetFromQueryTwo).find({
success: function(results) { /* do other stuff */ }
});
}
});
This works for a one-time query, but I'd like to use some of the more reactive features of Parse-React. So my question is, using Parse-React, can I make a component observe (in this example) QueryOne AND a QueryTwo depending on QueryOne?
I naively set out to implement this using by observing QueryOne in a parent component and passing that data as a prop to a child component, and observing QueryTwo from the child component, but I realize now that the observe function isn't triggered on prop updates so the query isn't rerun. Is there some way of triggering the query to rerun from componentWillUpdate?
I filed an issue directly on the parse-react github but haven't heard back. (https://github.com/ParsePlatform/ParseReact/issues/124) Would greatly appreciate any help! Thanks.
Got it! Turns out the observe function is passed newProps and newState as parameters, so if I make QueryOne in the parent container and pass the child the props, I can then use in the containedIn filter on the child with newProps and it works as expected.

What is the best place to put onEnter, onExit callback functionality?

I am creating my first project that uses ui-router.
My project has about 10 views, each with their own controller and state. I am trying to modularise/encapsulate/decouple as best as possible but I am having trouble working out where to put the onExit and onEnter state callbacks.
The first option is to put it in app.js which is currently defining all of my states, however I feel that this would not be a good place as it could cause this file to blow up and become hard to read as more states are introduced and the logic gets more complex.
The second option I looked into was to put it into a controller (I have one for each state), however from researching it doesn't seem to be best practice to do this.
The third option is to create a service that is resolved, however with this option I would end up with either a giant service full of state change functions for each of the states (not decoupled) or an additional service per state which would contain the state change functionality, and I worry that would increase project complexity.
What is the standard way to achieve this?
Are there any other options that I am missing?
Our strategy for this has been to disregard the onEnter and onExit on the state object, because as you are discovering, they feel like they are in the wrong place in terms of separation of concerns (app.js).
For onEnter: we handle setup in an activate() function in each controller, which we manually execute inside the controller. This happens to also match the callback that will get executed in Angular 2.0, which was not an accident ;).
function activate() {
// your setup code here
}
// execute it. this line can be removed in Angular 2.0
activate();
For onExit: We rarely need an exit callback, but when we do, we listen for the $scope $destroy event.
$scope.$on("$destroy", function() {
if (timer) {
$timeout.cancel(timer);
}
});

JayData with KendoGrid: entity set events not firing? Bug?

If I assigned a callback to an entity set event:
myContext.Items.beforeDelete = function(){ alert('before delete');}
myContext.Items.beforeUpdate = function(){ alert('before update');}
I get the alert messages if I delete or update a record. But if I use that entity set with a Kendo grid, I do not get any of the events? Is this a bug, or am I doing something wrong?
dataSource: myContext.Items.filter('it.IsDeleted == false').asKendoDataSource();
You've found the correct post, but it's the documentation not a workaround :).
The code you've tried isn't working probably because you should have written it before creating an instance of the context (for example by assigning the event handler in the model definition just like in the docs).
The solution (or work around) is to use the Entity Type events instead of the Entity Set events. I am not sure if this is a bug or not, but there is a clear work around.
See:
http://jaydata.org/blog/jaydata-event-handlers

I need a global event when data binding occurs in Knockout

I am a newbie to knockoutjs. I have searched examples and so far no luck. I have a page that is a data collection form with the values bound using knockout. What I am trying to do is provide the user with a flag letting him know data is modified and that it needs to be saved. In the app a user may pull down the form and display the data from the server and use it only as information. In other cases he may modify that data. I want to display a label that says something like "data has been modified" to the user once any binding has changed plus if he tries to navigate away from the page I want to warn him the changes will be lost. Is there some event I can subscribe to that tells me when any value has been changed in the model?
Thanks,
Terry
Take a look at Ryan Niemeyer's Dirty Flag. It might be what you are looking for. An example of his method can be seen in this jsFiddle.
this.dirtyItems = ko.computed(function() {
return ko.utils.arrayFilter(this.items(), function(item) {
return item.dirtyFlag.isDirty();
});
}, this);
More info can be found in this SO thread: Knockout isDirty example, using dynamic viewmodule from mapping plugin

Resources