What Is The Difference Between Pub/Sub And jQuery Data-Link? - javascript

A popular topic at the jQuery conference in Boston this month was the idea of Pub/Sub -
http://www.bennadel.com/blog/2037-Simple-Publication-And-Subscription-Functionality-Pub-Sub-With-jQuery.htm
A common example of what one may use PubSub to do is tracking for a piece of data changing value in order to execute some other event. As far as I know this can be done using either jQuery or the jQuery Data-Link plugin without requiring a PubSub architecture of your own.
What I would like to know is, what exactly are the differences between what PubSub has to offer and what simple data-binding does?.
Is it perhaps more efficient performance wise?

They are 2 separate beasts.
PubSub offers a way to maintain a pool of subscribers/notifications on a page. In other words, let's say you have 2 components on a page. Comp A publishes an event. Comp B is listening to the event. This way, they are decoupled from each others implementation and talk via messages (event args/data). Comp B can completely ignore the event or may choose to even not subscribe to it or it can react to the event and take further action.
jQuery Data Link is an automatic way of keeping data synchronized between 2 or more elements. Let's say you have 2 input elements on page. And you want the value of one to change whenever someone changes the value in the other one. For example, the other field might be a 'total' field and you want its value to be updated as soon as someone changes the first input's value.
Hope this helps.

Related

js / vue app doing CRUD, how can I track what needs updating?

I'm working on a vue app that uses vuex and gets objects from an api. The tables have paging and fetch batches of objects from the api, sometimes including related entities as nested objects. The UI allows some editing via inputs in a table, and adds via modals.
When the user wants to save all changes, I have a problem: how do I know what to patch via the api?
Idea 1: capture every change on every input and mark the object being edited as dirty
Idea 2: make a deep copy of the data after the fetch, and do a deep comparison to find out what's dirty
Idea 3: this is my question: please tell me that idea 3 exists and it's better than 1 or 2!
If the answer isn't idea 3, I'm really hoping it's not idea 1. There are so many inputs to attach change handlers to, and if the user edits something, then re-edits back to its original value, I'll have marked something dirty that really isn't.
The deep copy / deep compare at least isolates the problem to two places in code, but my sense is that there must be a better way. If this is the answer (also hoping not), do I build the deep copy / deep compare myself, or is there a package for it?
It looks like you have the final state on the UI and want to persist it on the server. Instead of sending over the delta - I would just send over the full final state and overwrite whatever there was on server side
So if you have user settings - instead of sending what settings were toggled - just send over the "this is what the new set of settings is"
Heavy stuff needs to be done on the server rather than the client most of the time. So I'll follow the answer given by Asad. You're not supposed to make huge objects diffs, it's 2022 so we need to think about performance.
Of course, it also depends of your app, what this is all about. Maybe your API guy is opposed to it for a specific reason (not only related to performance). Setup a meeting with your team/PO and check what is feasible.
You can always make something on your side too, looping on all inputs should be feasible without manually doing that yourself.
TLDR: this needs to be a discussion in your company with your very specific constrains/limitations. All "reasonable solutions" are already listed and you will probably not be able to go further because those kind of "opinion based" questions are not allowed anyway on SO.

Destroying Polymer-element and re-create new one with other attributes...or?

I'm wondering what's the best approach to do the following: I have a Polymer-element (PubNub (which handled Realtime Messaging)) which is "instantiated" with a some attribute values (the elements properties (more precisely, which channel to listen to/join)). And since the user should be able to switch chat rooms (/channels), I'm not sure if it's such a great idea to "instantiate" 5 PubNub-elements and in turn have 5 active chats going on in the background (receiving messages), if nothing else it would drain more battery power(?).
So, should I instantiate one PubNub-element and then remove and replace it when a user swaps channel? And how is this done best in Polymer?
Or is there some other approach one should take when dealing with this kind of problem?
You are right, the current pubnub-element is very basic and lacks many functionalities, as you have already noticed.
As Craig said, I don't generally recommend to create a bunch of instances either, however, the polymer element lacks the way you can modify all properties on the fly- you may be able to change the channel name as publishing, but it doesn't work the way for subscribing...
Instead of making some workaround using Polymer elements, I suggest to just use our vanilla JavaScript APIs. It maybe so much easier for your scenario.
And please do not hesitate to send us a pull requests or two :-)

Backbone.Radio: what's the advantage of commands and requests over events

It seems like Backbone.Radio provides 2 new abstractions - commands and requests. They're pretty much identical to Backbone.Events, except that they can have only 1 subscriber. Is that it, and if so what advantage do they provide over events?
I plan on using Backbone.Events/Radio with React.js, if that helps.
I have not actually used Backbone.Radio but do make extensive use of Backbone.wreqr https://github.com/marionettejs/backbone.wreqr which provides an almost identical command service.
In my usage the difference between events and commands is:
For events to work the sender and receiver of an event must both exist and have a reference to each other and the receiver must be in a position to deal with the event properly. This can often be problematic in a fully asynchronous browser environment where different parts of your application are running at the same time.
Commands allow you to decouple the sender and receiver. One object, lets say a View A, can simply send command 'update_user_details'.
My second Object View B sets up a command handler for 'update_user_details' which will change the user details on the screen.
But what if View B does not yet exist, or is not yet rendered. In the event listener pattern you would have to make sure View A exists, that it passes a reference to itself to View B and then you attach an event listener in View B.
With commands it is not a problem, View A sends a command, if no-one has set a handler then nothing bad happens, the command just does nothing.
When View B turns up, totally independent of View A, it sets a handler and will respond to all future commands.
Just a final note about intent:
The event pattern can be thought about in this way: I, View A have just done something, anyone that is interested (the event listeners) can do what they like about it, I View A don't care what you do.
In the command pattern: I View A want someone to do something, I don't care who does it, I just want it done right.
Channels. The key difference with Backbone.Radio over plain vanilla Backbone.Events that I have seen is that it allows you to setup channels to which your code can 'tune in' e.g. from the documentation:
var userChannel = Backbone.Radio.channel('user');
This means that logical functions or apps in your code can emit and handle events only on a specific channel - even if you emit events with the same name, if they're on different channels you won't get cross-contamination. This ties in nicely with the principles behind separation of duties in your code.
The other other difference, and IMHO it's subtle, more to do with elegance of coding than any real functionality difference, is that if you're telling something to respond to an event then it's really a Command, and Backbone.Radio allows you to separate these kinds of event into that type. Similar logic applies to the Requests type.
For completeness...
The docs also explain that a Channel is an object that has all three types of messages (Events, Commands and Requests) mixed in. You mix it into an object (I use Marionette so I'm mixing into an instance of Marionette.Object) using Underscore/Lo-Dash's .extend():
_.extend(objectToBeExtended, Backbone.Radio.Requests);
And the same for Commands of course. The syntax for events is different as that's baked into Backbone itself so the second parameter is just Backbone.Events.

jQuery: track multiple events in central location

Disclaimer: I am a designer with little jQuery knowledge. I will work with a JavaScript developer to realise this, but need to be able to write a detailed specification of my requirement.
I am looking to develop a platform which will track user behaviour via jQuery events API. Events, such as whether a user ‘points-and-clicks’ or tab’s to proceeding form fields will be scored, e.g. ‘point-and-click’ gets a -1 and tab gets a 2.
What is the best way of keeping track of all these event scores? My initial thought is an integer variable which increases and decreases in number depending upon user behaviour. The platform must also be able to:
be developed into a cookie
the value of the variable (if this is the best method) will inform which content to deliver to the viewstate via AJAX
I am happy to receive code snippets and/or written specification suggestions on how best to handle this.
Well, if your need is to be able to write a detailed specification of your requirements then copy/paste your question. It's ok like this.
Or make it more clear by removing your questionnings. If you're writing required specs, don't try to answer on how it should be done, just ask for what has to be done.
Track user behaviour via jQuery events API. Events, such as whether a
user ‘points-and-clicks’ or tab’s to proceeding form
fields.
You can add extra 'project management' infos like
date required
accessibility scope
some web development nice to write for a designer but useless for a developer stuff
budget
data chart / data flow
inputs/outputs

Is there a standard way of change tracking with a Knockout bound page?

I have a rather complex web page with various tabs, forms, radio buttons, drop downs, etc. It's all bound using Knockout.js to a very complex JavaScript object that was loaded via an AJAX call. Of course the user can muck with stuff to their heart's content, at which point they hit a Save button to persist all their changes back to the server.
I'm in the process of coming up with a good design to track exactly what was changed on the page so I can implement saving. So, I've come up with a few possible implementations.
Option 1) Just send everything back and let the server sort it out: With this method, I'd let Knockout just update the data source. The Save button would call .toJS() and send that data back to the server. Pros: It's super easy, and takes very little work on the client. Cons: The server doesn't really know what changed and has to either load the data from the database to compare, or just save all the fields again. These fields come from multiple tables and have complex relations. It also treats the entire document as a single atomic unit. If someone else changed Field A and you changed field B, one user is going to lose their change.
Option 2) Use JavaScript to compare the original data and the current data: Using this technique, when the user clicks on the Save button, I would systematically compare the original data and current data and generate a graph of changes. Pros: This would ideally result in a compact graph of exactly what the user changed, and could even no-op if nothing was changed. Cons: The data I'm binding to is complex. It consists of strings, arrays, objects, arrays of objects, arrays of objects with other objects, etc. Looking for changes would be a rather complex nested loop.
Option 3) Track changes as they are being made in the UI: I would have to observe changes as they happen, and keep a delta as UI elements were changed. The Save button would simply send that change graph to the server if it had any pending changes. Pros: No need to compare two huge JavaScript objects looking for changes, but still has all the benefits of option 2. Cons: Knockout doesn't appear to have a standard way to listen to all changes using a single event handler. I believe I would have to resort to binding to all the UI elements, or creating custom bindingHandlers in Knockout to implement this real-time change tracking.
My Question:
My question is mostly for Knockout.js experts. Is there a standard approach, or recommended guidelines to solving this obviously common scenario? Is sending back all the data, even stuff that hasn't changed, a common design? Or are people implementing custom change trackers? Does Knockout provide any sort of framework that eases this requirement?
Update: Found this thing, not sure if it could be useful or if anyone has any feedback on it.
If it's a question of enabling/disabling the Save button, allowing the user to navigate "from" that page/state, then you can check with the https://github.com/CodeSeven/kolite
check the knockout.dirtyFlag.js
Hope this helps.
Edit: remember that you should "never" trust the data coming from the "UI". The real comparison and validation, ultimately goes in your "controlled" environment within the server.
What I would probably do is take option 2 - the comparison itself can be as simple as stringifying the JS object and comparing it with a cached version of itself.
A few other options are discussed here.
P.S. Maybe ko.mapping can help you manage this monster of a JS object?
I wrote a change tracker extension for knockout that Pete Smith greatly expanded on...
Take a look here:
https://roysvork.wordpress.com/2014/01/12/tracking-changes-to-complex-viewmodels-with-knockout-js/
It works on the principle of extending the observable to track initial state vs. changes the user has made on the client. I think this works really great and can give users real-time feedback to know what they've modified. In practice, we actually implement a save panel that shows all pending changes and even lets them undo individual changes, all by using the change tracker's reusable capability.
ko.extenders.trackChange = function (target, track) {
if (track) {
target.isDirty = ko.observable(false);
target.originalValue = target();
target.subscribe(function (newValue) {
// use != not !== so numbers will equate naturally
target.isDirty(newValue != target.originalValue);
});
}
return target;
};

Categories

Resources