Hacker Timesnew | past | comments | ask | show | jobs | submitlogin

While I actually totally agree with the confusion in the router, I want to explain what I see in Ember's MVC:

As far as I attempted to implement it in my app (https://github.com/thomasboyt/noted-app), it seemed simple enough. Models were data; all they contained was their properties and operations that controlled their properties.

I mainly used controllers as the "state" for parts of my app. In Ember, this doesn't even need to mean it's tied to a specific model type. For example, my Dropbox integration is handled within a controller that's bound to several separate views (in this case, those views included buttons that triggered syncing and modals that displayed the progress of syncing). There's no "Dropbox model," just other models that I'm using this controller to sync. Controllers are not simply an intermediary between models and views, they are an intermediary between state and views.

> I'm trying my best to reconcile this with the notion that a controller (classically speaking) is supposed to ... well control the view. Here, it's not doing that.

I think what the author was looking for in controllers is what's actually handled by, well, views. The view handles any user interaction, and then uses the controller to change the state of various bits (whether calling methods in the controller or simply updating properties on it).

To sum up: model is data, controller is state (including instance(s) of models), and the view is user interaction. Templates can bind to properties on any of these. Routes are what hook these components together depending on the page.



Seems reasonable, but the Ember team sees it differently... they put state in the router:

>Most of your controllers will be very small. Unlike other frameworks, where the state of your application is spread amongst many controllers, in Ember.js, we encapsulate that state in the router. This allows your controllers to be lightweight and focused on one thing.


In this case, the "state" that we're talking about is "what state are you in". In other words, the router manages high-level state ("I am looking at a post now"), and provides long-lived controllers with data reflecting that state. So even though there is information about the current state in the controller (and the view), the source of truth about the current high-level state is in the router.


To expand slightly:

"Application state", rather than "stateful vs stateless" state. The router specifies "I'm looking at a post now" and the controller specifies "Looking at a post means loading this particular Post model as well as these comment models"


I've found a more specific term than 'high-level' state to explain the router state is 'addressable state'. A single page web application has two types of state. Addressable state (which is stored in the Ember router) and then another form of state, let's call it non-addressable state which is stored in the controllers.

As an example you could have a web application that has multiple documents and inside each document there are panels that can be expanded and collapsed. As you switch between documents each document maintains its own version of which panels are expanded or collapsed.

In the Ember world the router would maintain which document was opened (addressable state) and the DocumentController would maintain which panels are opened (non-addressable state).


Well, clearly, they are crazy people.

Nah, kidding. So they're totally right that there's a significant amount of state in the router, in that that's where you define which model and controller (and, depending on how fancy you get, what views and templates) to use on a given page. So those are essentially state.

The state that can make a controller fat is essentially state that's too important for a view but doesn't need to be universal to the page. For example, with my Dropbox controller, the controller has a state property that handles the various permutations of the state of syncing (i.e. it could be doing nothing, currently saving, done saving, failed saving, etc.). This state is set by the controller on the controller, and used by multiple views to determine things like which label a progress modal should have.

For example, if you had a controller representing a list, you might want to keep track of which item is selected on the controller. That way, if there are multiple views that can act on the currently selected item (for example - you might have a list item view that has a template that renders the item, and then a separate view that are buttons that trigger actions that act on the current item), they all have access to it.

Plus, I always think of state defined in a router as being limited to specific pages/routes, whereas some of my controllers are used on several different routes.


I rationalized this as the state-machine kind of state, of the application.


I think that that's exactly what it is. I've come to believe that every application needs a state machine that contains the shared logic and state that everything could possibly need to interact with.


Hence REST: "representational state transfer." Fielding also uses 'application state' to talk about this kind of state.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: