component / reactive

Tiny reactive template engine
382 stars 48 forks source link

nested properties are not handled properly on change events #112

Closed defunctzombie closed 10 years ago

defunctzombie commented 10 years ago
    var el = domify('<p>{name.first} {name.last}</p>');

    function User(fname, lname) {
      this.name = {
        first: fname,
        last: lname
      }
    }

    Emitter(User.prototype);

    var user = new User('Tobi', 'Foo');
    var view = reactive(el, user);

    assert.equal('Tobi Foo', el.textContent);

    // now change only a subfield
    user.name.first = 'Loki';
    user.emit('change name.first');
    assert.equal('Loki Foo', el.textContent);

Is this meant to work? Based on what I see when trying this it does not work.

anthonyshort commented 10 years ago

Nope, this won't work by default. But you can modify the get and set adapter methods to look for nested properties. I've use this https://github.com/eivindfjeldstad/dot component in the past to do the same thing.

Eventually this will probably work by default with Reactive though.

domachine commented 10 years ago

@anthonyshort well this sounds promising. could you give an example on how you did that?

anthonyshort commented 10 years ago
var dot = require('dot');
var view = reactive(el, model);
view.adapter.get = function(obj, prop){
   return dot.get(obj, prop);
};

Something like that should work. Or you could do it globally (which I wouldn't do since global Reactive is being removed).

var dot = require('dot');
reactive.get(function(prop){
   return dot.get(this.model, prop);
});
defunctzombie commented 10 years ago

Thanks for the pointer to dot. I've actually got a fork of reactive where I reworked the adapter bindings and compile step to fix these issues in a slightly more generic way. All fetching of properties goes through the assigned adapter via a .get call instead of the current way which has some leaky aspects.

https://github.com/component/reactive/blob/master/lib/utils.js#L137

I also changed how props are found by grabbing the whole key and not just the first part. This allowed me to remove some of the duplicate code and keep things better isolated.

Not sure how this will play with iteration since I haven't gotten there yet.