Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

Already on GitHub? Sign in to your account

multiple bindings #114

Merged
merged 0 commits into from Jan 22, 2014

Conversation

Projects
None yet
4 participants

Added support for multiple bindings, with a basic test case.

While this isn't going to be useful for most binders, like "text", etc., since one binding will always fire last, it does open up some new possibilities.

It allowed me to develop a "classes" binder for the class attribute that pulls class names from one or more bindings, which is powerful than the built-in boolean "class-*" binder, as it lets the data determine the class names to use. The multiple binding support was the only clean way to do this, instead of a repeated "class" binding, since HTML doesn't allow multiple element attributes with the same name.

Here's the binder from the test case:

rivets.binders.classes = function (el, value) {
    var elClass = ' ' + el.className + ' ';
    if (elClass.indexOf(' ' + value + ' ') === -1) {
      el.className = el.className + ' ' + value;
    }
    else {
      el.className = elClass.replace(' ' + value + ' ', ' ').trim();
    }
  };

And an example usage:

<div id="model">
   <div data-classes="model.shape, model.color"></div>
</div>
model = new Model({shape: 'square', color: 'red'}};
rivets.bind($('#model'), {model: model});

Results in:

<div id="model">
   <div class=" square red"></div>
</div>
Contributor

terrancesnyder commented Jan 6, 2013

Why not a custom binder?

rivets.binders['toggle-class-*'] = function(el, value) {
        if (value) {
            $(el).toggleClass(this.args[0], true);
        } else {
            $(el).toggleClass(this.args[0], false);
        }
    };

@terrancesnyder I'm not sure your example does the same thing. It gets the class name from the wildcard in the element attribute, not from the model value, which only controls whether that class is applied by coercing the value to a boolean. Isn't that what the built-in "data-class-*" binder does anyway?

My addition allows the class names to come from the model values, e.g. directly transferring a string value on the model to a class on the element.

For multiple classes like this, it is necessary to support multiple bindings since support for repeated HTML element attributes are not part of the DOM standard, don't work with jQuery, etc. The alternative would be to use dummy wildcards and have another "data-class-value-*" attribute for each class you want to bind, but that would be confusing and verbose.

Contributor

terrancesnyder commented Jan 12, 2013

@adjohnson916 understood given that you could have many different classes applied, and see your point. +1

@mikeric mikeric merged commit d82996d into mikeric:master Jan 22, 2014

@mikeric Thinking there wasn't interest, I removed these changes from my PR'd master branch and put them into my feature-multiple-bindings branch - which is probably way out of sync now.
I needed a clean master for branching to develop #253.
If interested, I can try to re-introduce the changes into a more recent code base.

Contributor

jhnns commented Jan 23, 2014

Interesting approach, your use-case seems reasonable. However, I'm not sure if this could introduce other problems.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment