Render
Last updated
Was this helpful?
Last updated
Was this helpful?
arguments:
fn(host: Element): Function
- callback function with host
argument; returned function has host
and target
arguments
options: Object
- an object, which has a following structure:
{ shadowRoot: true }
(default value) - initializes Shadow DOM and set target
as shadowRoot
{ shadowRoot: false }
- sets target
argument as host
,
{ shadowRoot: { extraOption: true, ... } }
- initializes Shadow DOM with passed options for attachShadow()
method
returns:
hybrid property descriptor, which resolves to a function (when called manually, it returns target
)
Render factory creates and updates the DOM structure of your custom element. It works out of the box with built-in , but the passed fn
function may use any external UI library that renders DOM.
Render factory trigger the update of the DOM by the observe
method of the descriptor. It means that an update is scheduled with the internal queue and executed in the next animation frame. The passed fn
is always called for the first time and when related properties change.
If you use render factory for wrapping other UI libraries, remember to access required properties from the host
synchronously in the body of fn
function (only then cache mechanism can save dependencies for the update). Otherwise, your function might be called only once.
Keep in mind that the options
can be passed only with render(fn, options)
factory function called explicitly:
You can trigger an update process by calling property manually from the element instance:
The render
factory uses the same cache mechanism like other properties. The update process calls fn
only if related properties have changed. However, calling myElement.render()
manually always invokes the result of the fn()
(it always triggers update process).
If your element should expose internal parts of the content as a public API, you can use render
property to define an internal DOM element from the rendered content as another property. Using render
in the getter of the defined property ensures that render process is called and it adds it to the dependencies of the property. The result of the call gives us a target
element, so you don't have to relay on the render configuration (it might be the shadowRoot
as well as the host
element - but both has querySelector
API):
The canvas
property from the above example will always reference the proper element from the shadowRoot. Even though the render process is asynchronous, if the user gets canvas
before the first scheduled render, it will return the element interface because of calling render()
manually. Moreover, the cache mechanism ensures that the canvas
property result is cached. It is recalculated only when dependencies of the render property change. This allows creating dynamic selectors, which returns different results depends on the render dependencies.
If you have more references to internal elements, you can create simple factory and use it multiple times:
Because of the asynchronous update mechanism, it might be tricky to test if the custom element instance renders correctly. However, you can create your unit tests based on the definition itself.
The render key is usually a function, which returns the update function. It can be called synchronously with mocked host and arbitrary target element (for example <div>
element):
If you use render
factory explicitly, your template definition can be defined outside of the factory call:
Click and play with render factory example using library:
Click and play with render factory using library:
The render
key of the property is not mandatory. The first rule of the allows setting fn
function as a render
property directly, and use the render factory implicitly:
The factory by default uses as a target
, which is initialized when the component is rendered for the first time. Usually, you can omit options
object and use rule for the render factory (described above).
Although, If your element does not require and (<slot>
element can be used only inside of the shadowRoot
) you can disable Shadow DOM in the options
object. Then, target
argument of the update function becomes a host
. As a result, your template will replace children's content of the custom element.