6 ms·
I have a question, since this has been bugging me with other js MV* frameworks lately... Is the set() method necessary for updating single attribute? All browse
by mannix 13y ago
I have a question, since this has been bugging me with other js MV* frameworks lately... Is the set() method necessary for updating single attribute? All browsers have supported getter/setter APIs (__defineGetter__ and Object.defineProperty), why not take advantage of them? Being able to say this would be cool:
div.color = 'blue';
instead of:
div.set({ color: 'blue' }); or div.set('color', 'blue');
Or would this cause other problems that I'm not thinking of?
Edit: my ruby cap is on a little tight today. Javascript programmers might not expect extra logic to be run just by updating a property. I still think it would be cool though :)
- nailer 13y agoES5 specifically has Object.defineProperty. Which works on all current browsers and Node. Rich what do you think?
- plorkyeran 13y agoIE8 doesn't support it for non-DOM objects.
- mannix 13y agoCrap. you're right. that's probably a dealbreaker.
- mnemonik 13y agoMany of these frameworks want to support IE 8, which is the default browser of windows 7. IE 8 only supports Object.defineProperty with DOM objects[0], which can be infuriating. No one should use __defineGetter__ and __defineSetter__ because they are non-standard and deprecated[1]. [0] http://kangax.github.io/es5-compat-table/#define-property-ie-note http://kangax.github.io/es5-compat-table/#define-property-ie... [1] https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/defineGetter https://developer.mozilla.org/en-US/docs/Web/JavaScript/Refe... Edit: left this tab open and I see this point has since been made, but I will leave the comment anyways.
- mannix 13y agoYes, the only reason I'd use __defineGetter__ would be a fallback for Object#defineProperty. I'm curious if the IE8 limitation could be worked around, using something like: if (ie8) RactiveBaseModel.prototype = HTMLAnchorElement.prototype;
- emn13 13y agoIf getters/setters aren't available, I still vastly prefer plain functions (e.g. knockout) to the stringized setter. I mean, why would model.set('someProp', 'someVal'); x = model.get('someProp'); be better than model.someProp('someVal'); x = model.someProp(); And the second one is likely to perform better, allows better tooling support (nice to have), is shorter, and allows representing a property as a concept in itself `model.someProp`. You can still access a property with a variable name in the (unusual) case you need to. If you really insist on explicit set/get, then you can still have... model.someProp.set('someVal'); x = model.someProp.get(); Which still has no downside I can think of, and since this is JS, if you have a variable prop name, you can fall back to... Pretty please, will the unnecessary strings die?
- rich_harris 13y agoIt's definitely something I've thought about. There are a few reasons I still prefer ractive.set( keypath, value ), which I'll try and articulate: 1. It's explicit, and therefore more predictable. I get itchy when libraries take control out of my hands. Though I understand not everyone feels that way! 2. Performance. Getters and setters have a penalty (or did the last time I looked into it in any depth). 3. It only works for existing properties. With Ractive you don't have to declare the 'shape' of your entire model up-front - you can start with a completely empty model and set properties as and when it's convenient. (With ES6 and Object.observe maybe we can sidestep that issue one day.) 4. Performance (again). If you set several properties simultaneously (e.g. ractive.set({ opacity: 0.5, left: 10 }), or whatever), then updates won't happen until all the new data has been taken account of. 5. That irritating thing that happens when you try to do foo.bar.baz = 'bob' and you get an error because foo.bar is undefined. 6. There are some cases where you want to do something like ractive.set( keypath + '.complete', true ) - you can only do that with string-based keypaths. As for emn13's suggestion of Knockout-style observables, my own experience is that having to inherit from custom observable classes gets cumbersome quite quickly. But different strokes for different folks!