Newer Version Available
Client-Side Rendering to the DOM
The DOM is the language-independent model for representing and interacting with objects in HTML and XML documents. The framework automatically renders your components so you don't have to know anything more about rendering unless you need to customize the default rendering behavior for a component.
You should never modify the DOM outside a renderer. However, you can read from the DOM outside a renderer.
Rendering Lifecycle
The rendering lifecycle automatically handles rendering and rerendering of components whenever the underlying data changes. Here is an outline of the rendering lifecycle.
- A browser event triggers one or more Lightning events.
- Each Lightning event triggers one or more actions that can update data. The updated data can fire more events.
- The rendering service tracks the stack of events that are fired.
- When all the data updates from the events are processed, the framework rerenders all the components that own modified data.
For more information, see Events Fired During the Rendering Lifecycle.
Base Component Rendering
The base component in the framework is aura:component. Every component extends this base component.
The renderer for aura:component is in componentRenderer.js. This renderer has base implementations for the render(), rerender(), afterRender(), and unrender() functions. The framework calls these functions as part of the rendering lifecycle. We will learn more about them in this topic. You can override the base rendering functions in a custom renderer.
Creating a Renderer
You don't normally have to write a custom renderer, but if you want to customize rendering behavior, you can create a client-side renderer in a component bundle. A renderer file is part of the component bundle and is auto-wired if you follow the naming convention, <componentName>Renderer.js. For example, the renderer for sample.cmp would be in sampleRenderer.js.
To reuse a renderer from another component, you can use the renderer system attribute in aura:component instead. For example, this component uses the auto-wired renderer for auradocs.sampleComponent in auradocs/sampleComponent/sampleComponentRenderer.js.
1swfobject.registerObject("clippy.codeblock-0", "9");
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17<aura:component
18 renderer="js://auradocs.sampleComponent">
19 ...
20</aura:component>Customizing Component Rendering
Customize rendering by creating a render() function in your component's renderer to override the base render() function, which updates the DOM.
The render() function typically returns a DOM node, an array of DOM nodes, or nothing. The base HTML component expects DOM nodes when it renders a component.
You generally want to extend default rendering by calling superRender() from your render() function before you add your custom rendering code. Calling superRender() creates the DOM nodes specified in the markup.
Rerendering Components
When an event is fired, it may trigger actions to change data and call rerender() on affected components. The rerender() function enables components to update themselves based on updates to other components since they were last rendered. This function doesn't return a value.
The framework automatically calls rerender() if you update data in a component. You only have to explicitly call rerender() if you haven't updated the data but you still want to rerender the component.
You generally want to extend default rerendering by calling superRerender() from your renderer() function before you add your custom rerendering code. Calling superRerender() chains the rerendering to the components in the body attribute.
Accessing the DOM After Rendering
The afterRender() function enables you to interact with the DOM tree after the framework’s rendering service has inserted DOM elements. It's not necessarily the final call in the rendering lifecycle; it's simply called after render() and it doesn't return a value.
You generally want to extend default after rendering by calling superAfterRender() function before you add your custom code.
Unrendering Components
The base unrender() function deletes all the DOM nodes rendered by a component's render() function. It is called by the framework when a component is being destroyed. Customize this behavior by overriding unrender() in your component's renderer. This can be useful when you are working with third-party libraries that are not native to the framework.
You generally want to extend default unrendering by calling superUnrender() from your unrender() function before you add your custom code.
Rendering Example
Let's look at the button component to see how it customizes the base rendering behavior. It is important to know that every tag in markup, including standard HTML tags, has an underlying component representation. Therefore, the framework’s rendering service uses the same process to render standard HTML tags or custom components that you create.
View the source for ui:button. Note that the button component includes a disabled attribute to track the disabled status for the component in a Boolean.
1swfobject.registerObject("clippy.codeblock-1", "9");
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17<aura:attribute name="disabled" type="Boolean" default="false"/>In button.cmp, onclick is set to {!c.press}.
The renderer for the button component is buttonRenderer.js. The button component overrides the default render() function.
1swfobject.registerObject("clippy.codeblock-2", "9");
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17render : function(cmp, helper) {
18 var ret = this.superRender();
19 helper.updateDisabled(cmp);
20 return ret;
21},The first line calls the superRender() function to invoke the default rendering behavior. The helper.updateDisabled(cmp) call invokes a helper function to customize the rendering.
Let's look at the updateDisabled(cmp) function in buttonHelper.js.
1swfobject.registerObject("clippy.codeblock-3", "9");
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17updateDisabled: function(cmp) {
18 if (cmp.get("v.disabled")) {
19 var disabled = $A.util.getBooleanValue(cmp.get("v.disabled"));
20 var button = cmp.find("button");
21 if (button) {
22 var element = button.getElement();
23 if (element) {
24 if (disabled) {
25 element.setAttribute('disabled', 'disabled');
26 } else {
27 element.removeAttribute('disabled');
28 }
29 }
30 }
31 }
32}The updateDisabled(cmp) function translates the Boolean disabled value to the value expected in HTML, where the attribute doesn't exist or is set to disabled.
It uses cmp.find("button") to retrieve a unique component. Note that button.cmp uses aura:id="button" to uniquely identify the component. button.getElement() returns the DOM element.
The rerender() function in buttonRenderer.js is very similar to the render() function. Note that it also calls updateDisabled(cmp).
1swfobject.registerObject("clippy.codeblock-4", "9");
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17rerender : function(cmp, helper){
18 this.superRerender();
19 helper.updateDisabled(cmp);
20}Rendering components is part of the lifecycle of the framework and it's a bit trickier to demonstrate than some other concepts. The takeaway is that you don't need to think about it unless you need to customize the default rendering behavior for a component.