Stages & Components: Single Root Template
What are we learning here?
Stages & Components Relations: ┌──────────────────────┐
┌─optional────►│ Component Element(s) │
┌───────────────┐ ┌───────────┐ │ └──────────────────────┘
│ Initial Stage ├─load──►│ Component ├─provides─┤
└───────────────┘ └───────────┘ │ ┌──────────┐
▲ └─at least one─►│ Stage(s) │
│ └────┬─────┘
│ │
└ ─ ─ ─ ─ ─ ─ ─ ─ load ─ ─ ─ ─ ─ ─ ─ ─┘
System Hierarchy:
► Initial Stage
└► Root Component
└► Stage "main"
└► Application
└► Stage "main"
└► Widget
└► Component Element "main"
- Each component element can be replaced with
this.element.replaceWith()
As you have seen we have used a separate HTML file where we have defined the inner structure for use in a component element. Some times such a HTML template have to be a single root template. This means that the template has only one HTML element in the root.
In this case it makes sense to replace the component element with the root element of the template
instead of using this as inner HTML. If you use such a template, you should always use it with
replaceWith
instead of innerHTML
, as this saves a div element.
Let's wrap our previous template for our first widget in a div
(because we do not want to use the
h2
tag as root element):
src/demo/apps/component-basics/content.ejs.html
1 2 3 |
|
And now we will replace the statement this.element.innerHTML = tpl;
with
this.element.replaceWith(tpl);
:
src/demo/apps/component-basics/content.js
1 2 3 4 5 6 7 8 9 10 11 12 13 |
|
But why do we mention this here in a separate chapter? Isn't that a standard method of an Element
instance?
No it is not exactly the case here. The property this.element
is a proxy of an Element
instance
and handles some functions differently and provides some additional functions that we will explore
in future chapters.
For example, the replaceWith
method we use here will copy the styles, classes and some other
attributes from the origin element. And as you can see, you can continue to use this.element
even
after the replacement.
Furthermore the proxy do not allow to replace the component element with multiple nodes or remove them.
Try the edge cases
All the following code examples replacing this.element.replaceWith(tpl)
will throw an error:
this.element.replaceWith(
document.createElement("div"),
document.createElement("div")
);
this.element.replaceWith("<div>one</div>", "<div>two</div>");
this.element.replaceWith("<div>one</div><div>two</div>");
this.element.remove();
Don't Remove Styles and Classes manually
The proxy already makes sure that if you want to replace the element, the original styles and
classes are copied. However, this does not prevent you from removing the styles and classes
individually or all manually (e.g. with element.styles.cssText=""
or element.className=""
).
This is dangerous because each component element is prepared for its environment. Removing classes or styles can cause the layout to collapse.
For this purpose, the component element offers two helper functions: element.resetStyle()
and
.resetClass()
. These functions remove all styles and classes, but restore the original state.