I have traditional Rails 4 app with a little bit of jQuery goodness here and the
ID: 657272 • Letter: I
Question
I have traditional Rails 4 app with a little bit of jQuery goodness here and there (so little it sits in couple of .js files just wrapped it $(document).ready) for some real minor things like cropping avatar images, enabling select2 autocomplete, ocassional handler here and there.
Thing is, requirements change and I basically have to provide users with simple switch to choose preferred units of measurements for width/height. I store things in metric units in db and was thinking of some kind of data-binding library which would allow me to implement those converions client-side. I also have couple of pieces of HTML/JS with hidden inputs and lots of spans with text which could benefit from abstracting in some way, since mess of click handlers with .hide(), .show(), .val() calls everywhere isn't very clean.
Problem is, there are literally dozens of data-binding libs nowadays and I have very brief experience only with knockout.js. It's quite lightweight but Models tend to grow very quickly and I dislike conditional comments in views (feels not so clean). Are there any better alternatives?
My requirements:
I want to keep my app conventional Rails app. I'm not going SPA, at least yet. I render the page, lib binds to certain elements, grabs rendered values and starts it's magick.
I want it to be lightweight. jQuery dependency is ok, but no Underscore please (I'm not big fan of learning any other DOM-manipulation/ajax/helper functions lib).
It's nice if it won't be too hard to learn with 200 pages documentation and fancy new names for old programming concepts everywhere. Good perfomance and IE8 support.
Explanation / Answer
Actually, I've gone with knockout.js for now, it became more mature since last time I checked(almost 2 years), with very good web-components support, AMD loader support and better memory management with pureComputed; although the community is somewhat smaller than backbone/angular.
Basically I've built custom bindings which initialize observables with values rendered by Rails in the view like so:
ko.bindingHandlers.initValue = {
init: function(element, valueAccessor) {
var value = valueAccessor();
// note that this binding plays well with writable computed observables
if (!ko.isWriteableObservable(value)) {
throw new Error('Your error message');
}
value(element.value);
which is then applied in the view for observable you want. You can have similar bindings for initChecked and whatever else comes to your mind.
Such bindings allow me to use Rails the conventional way without building API's and slinging JSON, but have my share of data-binding and client-side features to enhance user experience (example: convert weight/height on the page on the fly, with different inputs for either units system without extra requests to server. Or just about any complex DOM behaviour.
I'll be sure to revisit the answer when/if the project will grow to leave feedback on how well knockout scales on larger codebase.