Skip to content

Instantly share code, notes, and snippets.

@cdaringe
Created May 31, 2015 21:31
Show Gist options
  • Save cdaringe/928eccc55121ded4c4d5 to your computer and use it in GitHub Desktop.
Save cdaringe/928eccc55121ded4c4d5 to your computer and use it in GitHub Desktop.
rendered implementation discussion
// Solutions to manage the rendered state *better*
1. make `rendered` a bool member of `props`. manage rendered bit on your own
- weaknesses
- it's a pain for the user to have to explicty set `this.rendered` on every render and remove call, despite being a single bit
- it get's tricky if you extend muliple view definitions. If you manually set the rendered bit in each child's render function, you get duplicate 'change:rendered' events
2. make `rendered` a bool member of `props`. wrap user defined render()s to contain their render() fn AND logic to update `rendered`
- weaknesses
- again, each version of render() in the proto chain execs the fn and duplicate change events on the `rendered` prop occur
3. make `rendered` a bool member of `derived`. introduce {session: _rendered: [...]}, which the module uses internally for setting `rendered` state indirectly. this implementation also wraps the user provided render/remove functions and sets the _rendered bit, similair to the solution above. the `rendered` prop is dependent on and listening to the `_rendered` prop. Due to the caching nature of derived properties, a `changed:rendered` event only gets fired once, regardless of how many times parent View methods update `this._rendered = true` on a render() call. example:
```js
// &-view
_setRender: function(obj) {
Object.defineProperty(obj, 'render', {
get: function() {
return this._render;
},
set: function(fn) {
this._render = function() {
fn.apply(this, arguments);
this._rendered = true;
return this;
};
}
});
},
...
// ex
// recall that in this implementation, every call to a render function, regardless
// of whether View was extended or not, is going to set `view._rendered = true;`
var ChildView = AmpersandView.extend({
render: function() {
AmpersandView.prototype.render.call(this); // third render call
t.ok(true, 'child view render called');
}
});
var GrandChildView = AmpersandView.extend({
render: function() {
ChildView.prototype.render.call(this); // second render call
t.ok(true, 'grand child view render called');
}
});
var view = new GrandChildView({
template: '<span></span>',
el: document.createElement('div')
});
view.on('render', function(view, value) {
++renderCount; //=> 1, not 3. phew.
t.ok(true, 'view `render` event happened on `render()`');
});
view.render(); // first render call
});
```
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment