Skip to content

Instantly share code, notes, and snippets.

@sody
Created September 8, 2012 10:50
Show Gist options
  • Save sody/3673418 to your computer and use it in GitHub Desktop.
Save sody/3673418 to your computer and use it in GitHub Desktop.
Tepastry Render Deferred
<t:actionlink t:id="updateLeft" zone="prop:leftZoneId"
rel="tooltip" title="zone=${prop:leftZoneId}" class="btn">
${message:label.update}
</t:actionlink>
<br/><br/>
<t:zone t:id="leftZone">
<div class="hero-unit">
<p>${message:message.help-text}</p>
<p>${leftContent}</p>
</div>
</t:zone>
public class Deferred extends BasePage {
@InjectComponent
private Zone leftZone;
@Property
private String leftContent;
@Persist
private int leftTimes;
public String getLeftZoneId() {
return leftZone.getClientId();
}
@OnEvent(component = "updateLeft")
Object updateLeftContent() {
leftContent = format("message.content-text", ++leftTimes);
return leftZone;
}
}
boolean beginRender(MarkupWriter writer) {
decorator.beforeLabel(field);
labelElement = writer.element("label");
resources.renderInformalParameters(writer);
// Since we don't know if the field has rendered yet, we need to defer writing the for and id
// attributes until we know the field has rendered (and set its clientId property). That's
// exactly what Heartbeat is for.
updateAttributes();
return !ignoreBody;
}
@HeartbeatDeferred
private void updateAttributes() {
String fieldId = field.getClientId();
labelElement.forceAttributes("for", fieldId);
decorator.insideLabel(field, labelElement);
}
<t:actionlink t:id="updateLeft" t:mixins="RenderDeferred"
zone="prop:leftZoneId"
rel="tooltip" title="zone=${prop:leftZoneId}" class="btn">
${message:label.update}
</t:actionlink>
<br/><br/>
<t:zone t:id="leftZone">
<div class="hero-unit">
<p>${message:message.help-text}</p>
<p>${leftContent}</p>
</div>
</t:zone>
public class RenderDeferred {
@InjectContainer
private Component container;
private Element placeholder;
@SetupRender
boolean setup(final MarkupWriter writer) {
if (placeholder != null) {
// render container markup in deferred phase
return true;
}
// render placeholder element
// it will mark where the original markup should be placed
placeholder = writer.element("deferred");
writer.end();
// store heartbeat deferred action
// it will render real container markup
render();
// stop rendering container
return false;
}
@HeartbeatDeferred
void render() {
// create fake render queue and markup writer
final RenderQueueImpl queue = new RenderQueueImpl(LoggerFactory.getLogger(getClass()));
final MarkupWriter writer = new MarkupWriterImpl();
// create root element
final Element root = writer.element("root");
// render container component with fake markup writer
queue.push((RenderCommand) container.getComponentResources());
queue.run(writer);
// move rendered elements to real DOM
for (Node node : root.getChildren()) {
node.moveBefore(placeholder);
}
// remove placeholder
placeholder.remove();
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment