I have a controller that I use to toggle a set of links (that are littered throughout my page):
import { Controller } from "stimulus"
export default class extends Controller {
static targets = [
"edit",
"insert"
]
connect() {
this.apply_insert_mode( false )
for ( var insert of this.inserts ) {
// Remove the style, so we can control things with classes
insert.removeAttribute("style")
}
}
toggle() {
event.preventDefault()
this.apply_insert_mode( !this.insert_mode );
}
apply_insert_mode( insert_mode ) {
this.insert_mode = insert_mode
for ( var edit of this.edits ) {
if ( insert_mode ) {
edit.classList.add( "hidden" )
} else {
edit.classList.remove( "hidden" )
}
}
for ( var insert of this.inserts ) {
if ( insert_mode ) {
insert.classList.remove( "hidden" )
} else {
insert.classList.add( "hidden" )
}
}
};
get edits() {
return this.editTargets
}
get inserts() {
return this.insertTargets
}
}
Initially all the Edit links are shown. Clicking a “Switch” link will call toggle()
and hide all the Edit links and show the Insert links. With traditional server rendered html, this works a treat!
However, I’m playing around with Phoenix Live View. So now, parts of the DOM is dynamically updated. The net effect of this is that some Edit/Insert links are re-rendered. New Edit/Insert links can also be added to the DOM. However, the main problem is that the controller node is never updated. Which means that the targets are constantly changing, but the controller is never re-connected.
I’m assuming that this isn’t what Stimulus is for. But is there something I could do to address this? Can I manually update the list of targets when the DOM changes (using a Phoenix Live View hook)? I’m thinking maybe I could have a global list that I update manually and the controller can access the global list - but that feels like I’m re-writing what Stimulus does.
Any suggestions?