How To Access The Children Of Tagless Ember Components

A tagless component in Ember.js can be a simple way to implement functionality without adding an extra surrounding DOM node, but how do you access its child elements when it's tagless?

There is actually a good way to access the children of a tagless component using public methods. But first, I should explain some of the aspects of tagless components.

In Ember.js, when a component's tagName is set to an empty string, that tells the component to only render its contents but without a surrounding element. This means that if you try to access this.element in a tagless component, it will return null instead of a DOM node.

Yet, without an element, a tagless component somehow knows where to render its contents inside of a template. This is because the renderer is very smart and keeps track of the bounds where a tagless component's children begin and end in the template.

Although you can't simply access this.children to obtain the child nodes out of the box, you can use the bounds to obtain them:

import Component from '@ember/component';

class NoTagComponent extends Component {
  tagName = '';

  get children(){
    const { parentElement, 
            lastNode } = this.renderer.getBounds(this),
            children   = [];
    let first, last;
    for(const child of parentElement.childNodes){
      if(child === firstNode) first = child;
      if(first && !last) children.push(child);
      if(child === lastNode) last = child;
    return children;

export default NoTagComponent;

Essentially, we run through the children of the parent element and only return those that are within the bounds of the firstChild and lastChild elements.

A lot of people might not see that as being the "Ember way". Personally, I see nothing wrong with accessing the DOM directly so long as Ember's lifecycle hooks are used for things like cleanup.