Relationship between controllers


#1

Already a fan of your new concept.
I’m wondering is there way to call an another controller action from a controller:

Let’s say we have a list of todos, each todo have a controller: todo_controller with actions like toggleState, Rename or set estimate.
We have a project controller, it wraps these items and renders them, when change one todo’s estimate value to something else I want to recalculate the total estimate of the todos, so is there a way to call the project controller’s calculateEstimate action somehow from todo controller?


Iterating over controllers with same identifier
#2

Can I ask a related question from my toy application.

I have a project controller, inside it are a bunch of to do items that have an up and a down button (to reorder the items). Clicking the up or down triggers a state change, and calls the server to get the new list for display.

I’ve made each individual to do item an instance of a todo controller, and the project controller around it is an instance of a project controller.

When the todo up controller is clicked, is there a stimulus idiomatic way to get the parent project controller’s element to handle the refresh.

I tried making that element a target of the todo controller, but it’s not finding it, presumably because the target needs to be inside the scope of the controller element. I can find the correct element using the DOM, but that seems like I’m duplicating functionality. Is there a way to communicate between controllers?


#3

i ended up with this:

get projectController() {
  return this.application.getControllerForElementAndIdentifier(document.getElementById("projects-index"), "project")
}

so i can call this. projectController.refresh() whenever I want.

although it seems a bit hackish, i’m pretty sure there is a better way.


#4

See https://github.com/stimulusjs/stimulus/issues/35 for a related discussion.


#5

Hi,

I use this method:

  getControllerByIdentifier(identifier) {
    return this.application.controllers.find(controller => {
      return controller.context.identifier === identifier;
    });
  }

#6

I can’t make this suggested method work for me:

var controlled_element = $("*[data-controller='edit-quotation']").first()
if (controlled_element != undefined) {
    if (this.application.getControllerForElementAndIdentifier(controlled_element, "edit-quotation") == undefined) {
        console.log("FAILED: could not find the controller");
    }
}

The controller file name is edit_quotation_controller.js.
I tried alternative spellings to no avail (edit_quotation and editQuotation)


#7

In that discussion, @sam suggested: (emphasis mine)

The easiest thing to do is probably to emit a DOM event from the inner controller and observe it with an action from the outer controller.

How does one do that?