- Render widgets on NodeJS, where DOM is absent.
- Optimize rendering of Widgets at scale (1000s of TreeViewNodes).
- Avoid all Node references from Widget through the end of renderUI().
- bindUI()/syncUI() will still have Node references (to bind events and incrementally update DOM).
A boundingBox/contentBox Node instance won't be present for initializer/attr setters/attr getters/HTML_PARSER, so needs to be opt-in.
-
Component Developer can opt-in, if they have a 100% string rendered component (e.g. TreeViewNode)
In this case, get("boundingBox") etc. needs to be documented accordingly for the end user.
-
Environment can opt-in (e.g. NodeJS - conditional loading)
Example:
Y.WidgetStringRenderer = function() {...};
Y.WidgetStringRenderer.prototype = {
// override what needs to be overridden in Y.Widget to support string template based rendering.
}
Y.Foo = Y.Base.create("foo", Y.Widget, [Y.WidgetStringRenderer]);
It'll use Handlebar style templates as opposed to substitute, for forward compatibility.
However we should maybe look into a "handlebars-core" to satisfy the kweight nitpickers. We've been asked to break out less than 3KB chunks before which is where handlebars-base-min.js currently is.
"handlebars-core" could provide basic {{ }} and {{{ }}} support, and also maybe provide substitute compatibility (how to identify single { tokens, from content in a handlebars template?).
We'll need to break up the render()
phase, into the renderUI() portion and the bind/syncUI() portion
render()
renderUI() : No Node references
bindUI() : Node references
syncUI() : Node references
Not sure what the method split should be yet. Options are below, first one is my leading candidate
TreeView use case:
// While iterating 1000s treeview nodes ...
treeviewNode.renderHTML(buffer); // only renderUI() - is it OK that render event is not fired?
// I think so. Nothing is in the DOM yet.
// Once injected into the DOM ...
treeviewNode.render(); // renderUI() [if not invoked before], bindUI(), syncUI()
NodeJS use case:
// On Server
calendar.renderHTML();
// On Client
calendar.render();
Or,
treeviewNode.render();
treeviewNode.bind(); // How about if they want to do it all at once in render(); bind() and Y.bind() confusion
Or,
treeviewNode.renderHTML();
treeviewNode.bind();
Or,
treeviewNode.renderUI() // When do we fire/set render state?
treeviewNode.bindUI()
treeviewNode.syncUI()
Widget will generate node instance from rendered template content for boundingBox, contentBox
Y.TreeViewNode = Y.Base.create("treeViewNode", Y.Widget, [Y.Parent, Y.Child, Y.WidgetStringRenderer]);
// In Parent.render() ...
var buffer = [];
for (i = 0; i < children.length; i++) {
child.renderHTML(buffer);
}
var allChildrenHTML = buffer.join("");
// calendar-nodejs, or maybe just widget-base-nodejs
Y.Calendar = Y.Base.create("calendar", Y.Widget, [Y.WidgetStringRenderer]);
var buffer = []
calendar.renderHTML(buffer);
var calendarHTML = buffer.join("");
We can add sugar in the future (render straight into a template for example). Not enough time for Sprint 1.
calendar.renderHTML(template, token);
Hey guys,
I don't know how far you got with this (either the WidgetStringRenderer, or the MVC breakup of Widget), but in @sdesai's description of the new Widget (Base+Lifecycle+View+Model+Controller), how would the string renderer fit in there?
Would it be a plugin, an extension of the view that you compose in, or something else altogether?
We've run into the need for this in multiple components (trees, toolbar w/buttons, our textboxlist, and also other components custom to Liferay).
The other use case I can see, besides tree, would be building an entire UI from the JS. ExtJS recently did a kind of similar change in that they modified their rendering engine to do bulk updates so that each child component can contribute it's rendered state to it's owner (or parent) component, then at the end do one big render.
Basically, all components can have an owner, and the children all sit inside of the owner's (boudning|content)Box, and during some part of the lifecycle (probably render), the owner gathers up the children DOM (string or Nodes)*, and if it has an owner, pass it up, if it doesn't, flush the buffer of HTML into the render location.
I wonder for the P.E. scenario, I wonder if the same idea could be leveraged, where it contributes HTML_PARSER attributes, and right after render this is resolved.
*Resolving the contribution of either strings or nodes might be a bit hairy, though I can think of some ways to handle that, for instance, using stamped placeholder divs that are immediately swapped out with the component nodes on render)
Of course, you guys may have already solved all of this, and if so, ignore these as the ramblings of someone 6months behind :)