13 comments

[ 4.1 ms ] story [ 18.0 ms ] thread
The binding syntax looks pretty jenky. Why not use something standard and readable like json?
Nothing against the author at all, this seems like a cool little project, but I would never want to inline that much anything on a large project. Inlining things like that takes the maintainability and throws it out the window.
The main reason to write it into the HTML was to be more maintainable, by putting the presentation in the HTML presentation layer. Most libraries, such as rivets do very similar things for very similar reasons. When I know there's a data formatting issue in 1 element in the HTML, I can just fix that in the HTML. I don't need to go into the javascript and find which jquery snippet changes that HTML element and does the formatting.
Personally I would hate large amounts of logic in my attributes like that. I much think that properly formatted and structured JavaScript solves this problem much better. Especially when the same logic applies to two elements and you can create a function for it.
Rivets actually does a great job allowing you to create functions for similar formatting, which allows you to have very very short attributes, which in turn ends up being multiples of lines less than the equivalent javascript.
Pretty sweet. And an interesting implementation: https://github.com/mattinsler/spellbinder/blob/master/src/sp... (although more comments would be lovely). For prior art, see:

http://rivetsjs.com

http://nytimes.github.io/backbone.stickit/

But I have to say, that "example" is a pretty puffed up strawman. Most of the time, the real comparison is this:

    <p data-bind="count; [class:high-value] count > 100; [class:low-value] count < 50"></p>
To this:

    <p class="<%= count > 100 ? 'high-value' : (count < 50 ? 'low-value' : '') %>"></p>
With one exception. Spellbinder will add/remove classes as the model value is changed. It does the initial rendering and then will alter the html, style, classes, properties on the fly as you change the values in the model without reloading the page or re-rendering the view.
Yep, exactly -- which is a great thing to do for specific necessary cases, but usually a pervasive overuse of granular data-binding can cause large performance problems down the road. When the app has to track and manage each tiny attribute's expression in the eventual UI, there's a lot of overhead, and a lot of potential computation to be performed.

In a perfect world, you're able to bind changes in the data to changes in the view at the level of granularity at which your app needs to update. Most of the time, atomic chunks of HTML will be the most performant. Rarely, but sometimes, attributes.

A long-winded way of saying -- Great stuff! But be wary when starting to do it this way by default.

Absolutely!

We actually had a special case of a UI that needed to have many many things updating via push events, and have profiled it a few different ways. Turned out that with the frequency of updates we were making, larger chunks of HTML ended up being multiple times more expensive than adding a class here, or changing the text in a tag over there. This method actually _was_ the optimization.

Even so, the example is a tad puffed up:

    if (count > 100) {
      $el.removeClass('low-value');
      $el.addClass('high-value');
    } else if (count < 50) {
      $el.removeClass('high-value');
      $el.addClass('low-value');
    } else {
      $el.removeClass('high-value');
      $el.removeClass('low-value');
    }
Compare to how this would normally be written:

    $el.toggleClass('high-value', count > 100);
    $el.toggleClass('low-value', count < 50);
I did not know about this. Thanks!
Nice code, I'll update the readme to be more realistic.
isn't there a way to solve this with CSS3?

or at the very least, at the LESS/SCSS level?