You’re close, but I don’t think you’re all the way there yet.
There’s no “business logic” in a view- traditional MVC or ember. Anything that’s writing to or reading from your API, dealing with application state, talking to other controllers, etc. should be handled in your controller or your route. The primary purpose of a view, as the documentation states, is to turn browser events into “semantic” events. It’s a beautifully terse statement, but it can be a little cryptic if you don’t know what you’re looking for. Let’s talk through some examples:
“Click” is a browser event. So is swiping, inserting or removing a DOM element, expanding or contracting an accordion or whatever. These are things that could happen in any application, whether they’re Ember apps or not, or whether they’re your application or not. They’re just dealing with the magic of HTML and browsers.
A semantic event is something that’s particular your application. Submitting a form, toggling a property, going to a route- these are things that matter to your specific application, and would need to get done whether you were clicking a button, selecting something from a dropdown, howling at the moon, or punching the box in the perfect place.
If the user does a thing and an action happens, “does a thing” means view, “action” means controller. Here’s a magical piece of code that made this sink in for me:
Ember.View.extend({
click: function(){
this.get("controller").send("submitAnswer");
}
});
The view captures the click, and sends a message to the controller to do something. Note that absolutely none of this required templates. Some templates need their own view (partials just use their parent view, and “render” lets you set a specific view, as counterexamples), but a view does not need a template. Two examples:
// Some view named coolTemplate
Ember.View.extend({
templateName: "superCoolTemplate"
});
{{view coolTemplate}}
This will render a template named superCoolTemplate, and you could also attach all kinds of event handlers to it. For contrast, check out this:
// Some view named upvoteSinger
Ember.view.extend({
click: function(){
this.get("controller").send("upvoteSinger");
}
});
{{#view upvoteSinger}}
<div>Click me!</div>
{{/view}}
No template, all the HTML was “inlined” to the view because it’s in block form. It still handles all the same events, and has the benefit of being really flexible if what’s inside the block changes from instance to instance:
{{#view upvoteSinger}}
<div>She's a good singer, right?</div>
{{/view}}
Same click handler, sent to the same controller action, different HTML. The default HTML element wrapping any view is a div, but can be set to whatever, so you should really never do something like this:
{{#view someView}}
<section class="some-class">
<p>Saying something important</p>
</section>
{{/view}}
When you could do this:
// View named "someView"
Ember.view.extend({
tagName: "section",
classNames: ["someClass"]
});
{{#view someView}}
<p>Saying something important</p>
{{/view}}
When I said the templates from your routes get a free view that you can attach events and stuff to, that’s true, but it’s just one of their several uses.
What makes this different than a component is that a view still knows something about your application- like knowing that “click” means “upvote.” A components knows absolutely nothing about your application. It just gives your application an API to get or set its data. Think of a datepicker- you write:
{{datePicker componentDate=myApplicationDate}}
This component might put a control in your template that looks like a textbox, pull up a calendar when you click on it, and store the selection. That selection (“componentDate”) is exposed (and potentially even preset by the controller) by binding its value to the controller’s variable “myApplicationDate.” Whoever wrote that component doesn’t need to know that you’re using to select birthdays or whatever. Do you see how this is a special case for a type of view you might use? Views are reusable across YOUR application, components are reusable across ANYONE’s applications.
Lastly, some general MVC statements:
- Remember that M, V, and C are all about programming logic. The
confusing, dopey way I was taught this concept was “Models are
databases, Views are screens, and Controllers are the programs.” This
isn’t a healthy way to think about it. Rather, models are what talks
to the database, views are what create something like HTML that will
be rendered to a screen, and controllers are handling actions and
temporary state. An actual HTML template isn’t any of these things,
in traditional MVC or in ember. It’s the output of a view.
- Ember isn’t traditional MVC, but I don’t think it’s because of what
you’re describing. In traditional MVC, the user interfaces directly
with the controller, while in Ember it happens via the view. I think
this makes a million times more sense in a web framework, but I don’t
think it’s strictly the same implementation.
- Templates and routes aren’t a part of the traditional MVC story, but
not because are minor or because MVC is broken. It’s because
templates (even handlebars templates) aren’t really logic, and URL
routing is incredibly web specific. Routes can have logic and can
define models, but they’re really doing that on behalf of the
controller as a means of setting up initial state and state
transitions.
I hope I didn’t make it more confusing in the process of trying to explain it. Also, lest the great Ember god Tomhuda or any of his Core disciples smite me, I officially genuflect 7 times and caveat that I’m still as fresh as anyone and I might be incorrect on any of this. Views are the last things any of us learn because you can get so much done without needing to know anything about how they work, but they are truly an absolutely mandatory part of the puzzle to unravel if you want to fight off a confusion/frustration aneurysm.