gmac / backbone.epoxy

Declarative data binding and computed models for Backbone
http://epoxyjs.org
MIT License
615 stars 89 forks source link

Properties with dashes in their names #130

Open Mad-Chemist opened 8 years ago

Mad-Chemist commented 8 years ago

Hello. I was attempting to implement Epoxy earlier and had an error thrown once I had configured everything properly. The error seems avoidable if you do not use the with operator within the bindElementToView function.

I outlined the issue a bit in this stack overflow post.

Essentially what occurs is that my model has a property, lets say background-color, which cannot exist as a variable within JavaScript. When the parent object is passed into the with operator, it attempts to make background-color a block level local variable.

The following error gets thrown after attempting this above:

Uncaught Error parsing bindings: "value:background-color"
>> ReferenceError: background is not defined

Could the plugin accomplish this iteration manually or through some other means in order to avoid this issue cropping up?

Mad-Chemist commented 8 years ago

I've modified some code to remove the with operator and I'm wondering if I've replicated everything properly in doing so.

var parserFunct = bindingCache[declarations] || (bindingCache[declarations] =  new Function('$f','$c','with($f){with($c){return{'+ declarations +'}}}'));
var bindings = parserFunct(filters, context);

Where $f and $c are passed objects (From what I could tell, $f shouldn't ever have a property of $c). The declarations variable is a string that has a colon in it (EX: "value:color") and available within the scope.

Here is my modified code:

var parserFunct = bindingCache[declarations] || (bindingCache[declarations] = function($f, $c, declarations) {
        var result = {};
        var value = "";
        var split = declarations.split(":");
        if (split.length < 2) {
          throw new Error("Declaration is in an invalid format");
        }
        if ($f[$c] !== undefined && $f[$c][split[1]]) {
          value = $f[$c][split[1]];
        }
        else if ($c[split[1]]) {
          value =  $c[split[1]];
        }
        else if ($f[split[1]]) {
          value =  $f[split[1]];
        }
        else {
          value =  "" + split[1];
        }
        var key = split[0];
        result[key] = value;
        return result;
});
var bindings = parserFunct(filters, context, declarations);

Everything appears to work as it did previously, but this modification now handles the use case where the declarations variable could have a dash in it (EX: "value:background-color"). Additionally the declarations variable is passed into the function, to ensure it's defined.

Cross posted here: http://codereview.stackexchange.com/questions/113403/javascript-with-operator-removal