Are recursive controllers explicitly supported?


#1

I’m currently evaluating if Stimulus works for a current project and I wondered if it’s possible to use controllers recursively. E. g. for nested collapsible widgets (click on the header and the body shows or hides).

Here’s my current test implementation:

html code:

<div data-controller="collapsible">
  <div data-action="click->collapsible##toggleBody">Outer Collapsible</div>
  <div data-target="collapsible.body">
    <div>Outer Content</div>
    <div data-controller="collapsible">
      <div data-action="click->collapsible##toggleBody">Inner Collapsible</div>
      <div data-target="collapsible.body">
        <div>Inner Content</div>
      </div>
    </div>
  </div>
</div>

js code:

import { Controller } from '@stimulus/core'

export default class extends Controller {
  static get targets () {
    return ['body']
  }

  toggleBody () {
    this.bodyTargets.forEach(it => it.classList.toggle('show'))
  }
}

And, surprise: it works exactly as expected! The outer collapsible triggers only the outer content. Same for the inner ones.

Now I’d like to know if this is intended behaviour and officially supported or if this just works because I’m very lucky here. I can’t find any information about this kind of usage.


#2

Officially supported! And also not very well documented. Each controller has its own scope, which isolates it from others even when nested.


#3

Okay, this is really nice. Thank you.


#4

We call these nested scopes, and to echo what @javan says, they’re explicitly supported but not yet documented. I haven’t figured out how to explain them yet!


#5

This might bring up another question I already had in mind: What’s the name of that part of the HTML that contains the data-controller attribute? If you can name that you could explain it as simply as “You can nest XY.”. Or maybe “You can nest elements bound to the same controller.” would be just fine. But a name for said HTML fragments would still me helpful in some situations. Currently I’d call it “That element that has the data-controller attribute” which is rather long. But I don’t think that “template” or “component” are good names here.