Reusable component / view / template that is bound to controller?


I’ve been researching the discussions about when to use a view, component, render, or helper. There seems to be some conflicting information, but it seems like the developers advise against using a view, but recommend using components instead. Ok, but what if I want my ‘component’ to be bound to a controller? I would think I would then use {{render}} or {{partial}} but my understanding is that these are not designed to be reusable; that’s what a component is for?

As an example:

Suppose I have a model, let’s call it a ‘Task’ that can be displayed in a list, and is editable in that list view. And suppose I have a couple lists of tasks, like ‘overdue’, ‘completed’, etc.

So, I want something reusable that I can plug into the templates in my ‘tasks/index.hbs’, ‘tasks/overdue.hbs’, and ‘tasks/completed.hbs’ templates. This reusable component/template needs to be bound to a controller so that I can do actions like edit the task, mark it complete, assign it to somebody else, whatever.

The question is, do I make a template “task/list-item” and render it with

{{#each}}{{partial “task/list-item”}}{{/each}} assuming the ‘itemController’ property is set to ‘taskListItemController’, or similarly would I use

{{#each}}{{render “task/list-item” this}}{{/each}}

Or do I define a component {{task-list-item}}, and if so, how would I bind it to the controller?


As I understand it this is the structure of the problem it looks something like this.

{{overdue-component model="overdueTasks"}}
{{completed-component model=completedTasks}}

and inside the overdue / completed components there is

{{#each tasks as |task|}}
  {{task-component model=task}}

Your task-component also emits some actions like edit, assign, and complete which you have handlers for in the controller.

To get them to the controller THROUGH the intermediate component see action bubbling and event target.

Let me know if I misinterpreted your issue.


@varblob so it looks like you’re recommending using a component instead of render / partial. I see how it could work that way, though I still don’t understand why we would use that instead of a template that automatically has a controller associated with it.

As for the overdue / completed part, I was just setting that up with a route / template / controller; not packaging that as reusable, though it’s useful to see how one would do that.


Finally found a pretty detailed explanation here Looks like components are the way to go, and changes are coming to the way we bind controllers.


@leejt489 great link I haven’t read that one yet.