There are a couple of solutions for communicating between controllers, but each time I reach for Stimulus I find myself wanting to be able to compose controllers. This approach follows the declarative nature of targets, classes and values. Declare the parent and children and it will be so.
Here is a fork with the feature, including instructions on how to try it out from GitHub.
Definitions
Define parent
and children
names in your controller using static properties. Only one parent can be defined per controller.
// controllers/search_controller.js
import { Controller } from "stimulus"
export default class extends Controller {
static children = [ 'searchResult' ]
// …
}
// controllers/search_result_controller.js
import { Controller } from "stimulus"
export default class extends Controller {
static parent = [ 'search' ]
// …
}
Properties
For each child name defined in the static children
array, the following properties are added to your controller, where [name]
corresponds to the child’s name:
Kind | Name | Value |
---|---|---|
Singuluar | this.[name]Child | The first matching child |
Plural | this.[name]Children | An array of the children |
The parent is available as this.parent
regardless of the name specified.
Naming Conventions
Always use camelCase to specify parent and child names, since they map directly to properties on your controller. The names must match the controller identifier of the related controller.
For example, if the child the SearchResultController, then the identifier of the controller in the html is search-result
and the child name is searchResult
.
Callbacks
Before and after callbacks are available for the registration of both parent and child controllers.
To perform logic when a child is registered with a parent component, define either of the following methods on the parent, where [name]
corresponds to the child’s name:
before[name]ChildRegistration(childController)
after[name]ChildRegistration(childController)
To perform logic when a parent is registered with a child component, define either of the following methods on the child:
beforeParentRegistration(parentController)
afterParentRegistration(parentController)