What is best/worse practice of using containerless in view model or in view?
When to use containerless and when not to use containerless?
All this question I have in my mind after conversation I have with @boban.r
What is best/worse practice of using containerless in view model or in view?
When to use containerless and when not to use containerless?
All this question I have in my mind after conversation I have with @boban.r
I’ve used it in SVG where HTML components are not valid. It’s also useful if you want off the shelf CSS to work without modification.
Not an authoritative answer, but to share my experience.
As Aurelia document said, @containerless
does fight shadowdom which will be part of html standard, plus other quirks, use it sparingly.
We use @containerless
to avoid creating intermediate dom wrapper <my-comp>
that destroys inner element styles or position, right? How could we avoid using it as much as possible.
@containerless
with as-element
@containerless
by using<ul as-element="my-comp">
.<compose view-model="./my-comp">
,<compose>
tag?
@containerless
cannot fix this, but as-element
can.<ul as-element="compose" view-model="./my-comp">
.
@containerless
for svg partial, as-element
doesn’t workJust read Aurelia document. This is limited by browser’s native html parser (which Aurelia uses to parse every html template file), you need a <svg>
tag wrap in your svg partial template to teach browser parser you are writing svg, not html. (technically, svg is xml, not html)
You cannot stand the possibility that fellow developers might misuse your component directly as <my-comp>
, then ends up blaming you the broken style/layout. How to ensure the usage of as-element
?
Now you can shout back: “Read your console log, dumb ass!”.
import {inject} from 'aurelia-framework';
@inject(Element)
export class MyComp {
constructor(element) {
if (element.tagName === 'MY-COMP') {
throw new Error("cannot use <my-comp>. use <other-tag as-element=\"my-comp\">.");
}
if (element.tagName === 'COMPOSE') {
throw new Error("cannot use <compose view-model=\"my-comp\">. use <other-tag as-element=\"compose\" view-model=\"my-comp\">.");
}
}
}
import {inject} from 'aurelia-framework';
@inject(Element)
export class MyTableRow {
constructor(element) {
if (element.tagName !== 'TR') {
throw new Error("use <tr as-element=\"my-table-row\">.");
}
}
}
Just want to show one more off-topic tip, you can avoid intermediate <router-view>
tag.
<div class="row" as-element="router-view"></div>
Don’t be too surprised. compose
and router-view
are just custom elements, not much different from those you defined.
A good example of usage will be when you have list item as a component nested in list and you won’t break the style: ul > li { // CSS }
<ul>
<list-item>
<list-item>
…
</ul>
just out of curiosity , can we use as-element
on <template>
tag too?
<template as-element="my-custom-element">
</template>
I cannot test it right now
@huochunpeng <compose containerless></compose>
works . I’m using it in a couple of places without issue.
This also works:
<router-view id="main-router" containerless></router-view>
Well this is black magic of semantic markup (-:
this qoute from docs makes total sense:
Note that when a containerless attribute is used, the container is stripped after the browser has loaded the DOM elements, and as such this method cannot be used to transform non-HTML compliant structures into compliant ones!
For example
<select name="" id=""> <template repeat.for=""> <option value=""></option> </template> </select>
does not work in ie
I really appreciate what all of you write. Until this moment everywhere I use as-element but I was curious what @containerless do.
While creating one CE and using in table I figure that you need to use as-element=“table-head” because only like this browser knows how to render your CE.
So to sum up if I can (please correct me if I’m wrong )
I’d add : if you control markup - as-element is more compatible at the moment. with less styling needed.
Recently faced the need to use containerless
custom elements. I just want to point out that if you want to use your custom element with all the glory of binding, but don’t want to have the wrapping DOM element, then containerless
attribute is the best choice.
<my-element prop1.bind="value" containerless></my-element>
This makes specific instances of my-element
container-less, without impacting all instances of my-element
.
I know this is an old topic, but wanted to add the usefulness of containerless.
I’m working on a solution that dynamically creates Bootstrap toolbar buttons based on a JSON config file. There are instances where I have to do something like <div if.bind or <div repeat.for. These are only needed to make decisions and I don’t need actually need them in the final HTML. Because Bootstap button groups look different based on which elements are direct children or descendants these extra divs were making the UI look bad. Turning those divs into a custom element that’s containerless solved the problem for me. BTW, if you know of a better way of doing this let me know, lol!
Can I take an aside and just say how much I like Aurelia. I’ve been using it for a few years now and I’m amazed at how simple it’s able to solve problems I run into, like the above mentioned one. I feel like you just need to learn a few basic principles and that’s all you need, don’t need to learn all this special syntax like with some other frameworks.
I do think documentation could be better though. I had no idea containerless could be used directly in an HTML only custom element as the documentation only used it with a view-model. It was only by searching this thread that I saw I could use it as an HTML attribute. That one discovery completely changed I approached this problem. In any case, it is an awesome framework and wanted to give a note of appreciation to the creators/maintainers for a job well done in architecting it.