Could someone concisely summarize which responsibilities should be handled with Ember's routing system?
After 2 weeks with Ember, I suddenly feel like I don't have an accurate grasp of what routing does. It looks kind of does everything; establishing urls, setting arbitrary controllers/templates/etc, forwarding routes, pre/post load events for models, etc.
The broad capabilities of Ember Routing leave me uncertain what should be handled by the router vs an MVC object. The official docs (http://emberjs.com/guides/routing/) do a good job of explaining how to do many things, but kind of prevents me from seeing the forest for the trees...
A Conceptual Model
One way to think about it is that Routes & Controllers are both controllers in the MVC nomenclature. Controllers are concerned with controlling the connection between Models and their display, and getting data into and out of them, and Routes are concerned with controlling the connection between Models, between Models and the application, and between Models and their persistence layer.
Application: the granddaddy model
In this view Application is the granddaddy model (and it is always there: even if you don't explicitly refer to it there is an ApplicationRoute and ApplicationController being anonymously created). So naturally, routes control the connection between the Application and other Models.
The Most Common Setup
For a given model, there will typically be (as a basic starting point) two Routes and two Controllers. One Route manages the retrieval of a collection of the Model, and a corresponding Controller connects that collection to a view of the collection, and another Route manages the choosing of a single instance of the Model, binding it to a controller that manages its connection to a view.
Who handles Actions?
Views, Routes and Controllers can all intercept and handle actions. They each have a special ability that the others do not.
The Controller Special Ability
The special ability of Controllers is that they know about the specific instance or collection of a Model that the action concerns. If an action comes to a controller it is generally originating in a view element concerned with that controller's model. So, actions defined on controllers should do something with a model or model collection. If an action does not care about a model/collection, it probably belongs on a Route.
The Route Special Ability
The special ability of Routes is that they know the hierarchy into which models/collections have been organized. This means that they can do things involved with navigation more naturally than controllers can.
The View Special Ability
The special ability of Views is that they know about the interface, and events animation etc.
Handling Actions with multiple Handlers
Although it is not necessary, I often split an action into two (or even three) handlers, often with the same name. In the case of two, one handler lives on a Controller, and does the part of the action concerned with selecting, querying, or otherwise talking to a Model. The other handler lives on a route and is concerned with the navigational part of the action. When actions are split up this way, you find your app becomes easier to refactor, and you have to do less gymnastics to accommodate "weirdness" in the html structure of your views (in particular for negative actions like cancel or deselect).
Sometimes a third handler lives on the View and does jquery-ish things or css animation. In each case when a component has done their part of an action, it uses send to forward the action to the next component that should deal with it. Typically that means View->Controller->Route.
Summary
So to sum up, Routes should focus on managing the retrieval of models and the connections between them and between them and your app, handling the parts of actions concerned with navigation and app state. Controllers should focus on managing the connection of models with html view elements, handling the parts of actions concerned with choosing/unchoosing/modifying a particular model or model collection (note: choosing is usually switching to a new route, and handled by a Route. But sometimes controllers handle non-route choices, like setting an attribute on one model by choosing an item from a list of another model). Views should handle the parts of actions concerned with changing the html they represent, ie, animation, css changes that reflect state, etc.
I found a very concise and explanatory blogpost about routing: http://hashrocket.com/blog/posts/ember-routing-the-when-and-why-of-nesting
Understanding the proper use of the Router in an Ember.js app is a fundamental core concept of the framework. The docs tell us that the router translates a URL into a series of nested templates and almost all available tutorials show how to nest routes as part of an explanation of how the Router works.
This is great when you want a UI where a list of items are present at
the same time a single item is shown. This leaves many beginners
struggling, however, as they try and replace the entire contents of a
page with another route’s template. Today we’ll explore two ways to
tackle this problem.
Related
I'm scratching the surface with Angularjs, and thought I'd run a conceptual question past the fine folks of SO. This is a newbie question from a seasoned developer.
The application has dashboard requirements... a single page that surfaces stuff from many parts of the application. Different user types get different dashboards. We already have a legacy back end, so the first task is to build the dashboard to show many bits from it's new RESTful service layer.
I'm wondering how I should conceptually think about the controllers needed to support this?
The first question is... should they be model-centric or view-centric? In other words, should they be "view-centric" controllers that have the word "Dashboard" in them? Or should they be more focused on the model elements they represent, like "Tasks", "Contacts", "Notifications". Or should there be both where the dashboard controllers work with model-centric controllers?
The next question is... what level of granularity should the controllers represent? If view-centric "Dashboards" controllers, should they be "ManagerDashboardController" and "WorkerDashboardController"? If model-centric controllers, should there be controllers such as "LateTasks" & "OnTimeTasks" since I need to display them on different sections of the dashboard, with slightly different data?
I'm looking for tangible advice based on real-world experience and/or references to great links I've yet to find.
Here are my views from developing business applications in Angular for the past 6 months:
Role of a Controller
Initialization (loading initial data, setting options)
Exposing variables and functions to the template through the $scope
Application flow (through exposure of functions that can change state, or $watches)
I have found that, much like in traditional MVC frameworks, the controllers in an Angular app should really be super slim. Little if any business logic should be in the controllers, and should be instead be encapsulated in your models. I came to this conclusion after hearing the follow line from a presentation by Miško Hevery: "the purpose of the scope is to refer to the model and not be the model." That was the most valuable and enlightening line I got from that presentation (though I recommend to watch the whole video); that line directly resulted in me slimming down my controllers by almost 50%-70%.
For example, my company has a concept of an Order. I created a model that encapsulated all the properties of this business object, as well as its behaviours and injected them into the controllers. One business rule we had was the ability to add a Booking (another business object) to the Order. Originally in my controller, I had a $scope.addBooking function that first created a new Booking, then took the order and did a $scope.order.bookings.push(newBooking). Instead, I moved this business logic (addBooking function) directly into my Order model, and in the template I could then do something like <button ng-click="order.addBooking()">Add Booking</button> without adding a single line of code into my controller.
A lot of the code I put in my controllers when I was first starting off with angular, I found could be stripped out and placed either in my models, directives, or services (mostly the first two in my case). The remainder of the code left in my controllers almost all fell into one of the above 3 roles I listed above. It was either initialization code (e.g. firing an AJAX request to fetch data of the relevant business objects), scope assignment of objects, or scope assignment of functions that dealt with application flow (e.g. $scope.save or $scope.cancel that might send you back to a different page).
Should controllers be model-centric or view-centric?
This is an interesting question, one that I haven't thought about before. When I hear view-centric, I think of a controller that deals primarily with the view and how things are displayed. I feel there shouldn't be any controllers that are purely view-centric, the reason being it seems a view-centric controller can probably be transformed into a directive. You mentioned view-centric controllers as being like a Dashboard controller, which sounds like something that could definitely be made into a generic directive. Your directives should encapsulate most of your view logic, while your controllers focus on simply exposing your models to the view for consumption (back to the role of the controller). This has me thinking that controllers should more often be model-centric.
I think really the only conclusion I can come to is if a controller starts becoming too view-centric (with many variables and functions that deal primarily with the view and UI behaviour) then that is a sign that parts of your controller can be pulled out into a directive, making your controller slimmer.
This is very subjective but here is my answer to your questions
should controllers be model-centric or view-centric?
It depends (as always), I always try to have small controllers for the different parts of the page.
Some parts of the page are very view-centric (typically the ones that are shared among the different views). I usually have a menuCtrl, a headerCtrl and footerCtrl. This ctrls are very coupled to those parts of the page so a make them view-centric.
The other parts of the view, the ones that are business related are much more coupled to the business rules and in extension to the model so I make those ctrls model-centric. On an account´s business app, I would probably have an accountCtrl, an ownerCtrl, and so on. By doing so I can reuse them on different views if needed (and are much easier to test)
what level of granularity should the controllers represent?
The smallest as possible. Try to have small controllers that prepare the model for different parts of the page. If you have a big controller it will be hard to test, maintain and you will probably be forced to duplicate code on different parts of your application.
advices and recomentations with controllers
Keep them small.
Avoid DOM manipulation inside of them (use directives instead).
Use the controllers just to prepare the model. whenever possible delegate all the logic of your app to services. If you do so, it won´t really matter that much if your controller is view-centric or model-centric.
As I said before this is a very subjective matter and I´m sure many people will disagree with me.
I hope this could help you.
Basic Idea
So I'm actually in the process of migrating a legacy code base over to a restful based web service architecture utilizing AngularJs
Controllers are responsible for managing the data that is consumed by the view aka the webpage. My personal preference is that there is a one to one relationship between the controller and the view that it is serving. So, based on the question, Angular controllers should be more view centric. I'm sure that there are plenty of people who will disagree with me though.
If you are worried about the extensibility of this pattern, you should place your business logic and data access within Angular Services as described here. This offers you a tremendous amount of reuse of business logic operations as well as unit testability.
TLDR;
The specifications for Angular are changing all the time and with each new version there will be a new standard. A more view centric architecture looks appropriate for this application.
For some more complete reading on the subject I recommend checking out:
3 Tips To Building Enterprise Grade Angular/Node Applications
Lessons Learned: A Year with a Large AngularJS Project
I've learned that you should set up the controller-class in a MVC-OOD as a use case, from top to bottom in only one method that run the MVC-classes.
Is it OK to use different methods in one controller to get more control and better overview?
Let's say you wanna run a controller that will display a login form (getting the html etc from the View). And the same controller will also display a log-out button IF the user is NOT logged in.
This could be done with a single method in the controller, but using two methods seems better. One method to call if you want the login form, and one to call if you want to log-out button.
(just an example)
So, what does the pros say. Should each controller contain one "use case" method only, or could it be several?
TL;DR -- you have misunderstood the MVC design pattern and are doing it wrong.
Controllers are not responsible for rendering the interface, nor for presentation logic. Controllers do not display anything. Instead, each controller's method deals with different user's request. It extracts the data from said request and passes it to model layer and the associated view.
Decisions about what and how to display are in purview of views. Views contain the presentation logic in MVC pattern. In the context of web applications, views create the response. They can compose a from from multiple templates or just send a single HTTP header.
Controllers can signal the associated view by passing some specific values of the request to that view, but most of the decisions in the view are based on information that the view requested from different services in the model layer.
A Controller's methods are based on what type of requests a user can send. For example in a authentication form it might be: GET /login and/or POST /login.
Its important to remember two things with MVC, firstly, its an Object-Oriented Architecture, and secondly, It should be used for separating concerns.
Separation of Concerns is related to Abstraction, It is to aid us in understanding the section of code at hand. The Model and View are both collections/domains of related objects. Each object is fully complete and relevant to its domain.
You will find objects with types such as Buttons, Images, Text Inputs etc inside your View, and you will find business related objects (User, Account, Profile etc) within your Model.
The collection of objects inside your Model don't tend to do much, They require logic to wire the objects together. (Or simply delegate simple single object requests to the correct object)
The Controller provides the interface into your Model, and contains the business logic related to the Model and the interactions between the Model objects. You will have a single Controller for your Model, and the Controller will have multiple methods which will align with your use-cases.
I have a question concerning the structure of an MVC application. Suppose we have to realize a web-based application composed by several modules, such as shopping cart, store browser(end-user), store manager(admin) and so on.
It is of course possible to create one controller and use the routing to submit the requests to a specific controller's action method. However this would make the code quite messy and hinder the practice to vertically structure the application, namely to identify and distinguish which views, models and controllers are involved to fulfill a specific requirement (an example is given by Phil Haack).
Another approach is to use one controller for each application section, for instance one controller made available for end-user operations, another for the store administrator, another one for queries made by the shipping department and so on. The drawback to this approach is to have too many controllers that mess up your code, too dedicated for specific tasks and so difficult to reuse.
According to this two extreme situation, what is the best way to organize your controllers and routing policies? Do you use a structured approach or it depends on the type of application you are developing?
Thanks
Francesco
It is of course possible to create one controller and use the routing to submit the requests to a specific controller's action method. [...]
Another approach is to use one controller for each application section, [...]
You're overlooking a third alternative, which is the most common one. In general you should have one controller per resource. A resource is a model that is publicly exposed. In your specific storefront application, the resources would be things like Products, Orders, Customers, etc.
This is typically the proper level of abstraction, because controllers usually don't need to know about models other than the resources they touch. A controller that touches more than one resource should be viewed with some skepticism, since it's violating the single-responsibility principle.
You should try to follow REST as much as possible
Basically - that means controller for each 'collection' (Your entity).
If Your controllers will be RESTful, other parts (routing, views) will fit themselves accordingly.
I've done a fair amount of work on MVC on the web, and we're learning about it in my OOP class. I'm seeing some differences, and I can't tell whether that's because the Web's version of the MVC pattern is different than the traditional one, or whether I misunderstood it.
From my understanding, The model (your flat files, RDBMS', etc) is a generic data-housing object. The View (Browser, HTML, etc) is what the user interacts with, and the controller mediates between the users actions and the data. The controller is the most domain-specific part, and it manages the views, tells the model what it needs, and tells the views what to display.
In class, we have the Views matching what I just described, the Model contains a list of the views so that it can update them when the data changes, and the controller simply maps the user's actions to calls to the model and to specific objects (which may themselves, ask the model to update the views). What ends up happening is that most of the business logic is in the model, and it's tied very heavily to the simulation or application that is being written, while the Controller is reduced to a mapping tool between commands and methods.
What are your thoughts on this?
In a non-web interface the controller handles the inputs from things like the keyboard and mouse, choosing which views to render and what changes to make in the model based on those inputs. The view and model can be more closely related because the view can register callbacks directly with the model entities to be notified of changes and thus be updated based on changes to the model directly instead of being updated by the controller.
In the web world, views are necessarily more decoupled from the model. It must act through the controller actions because it has no direct access (after being rendered and delivered to the browser) to the model. The controller takes a larger role in this environment even though the only "input" it has to deal with are browser requests. In a sense, the coupling that used to occur with the view in non-web MVC is transferred to the controller acting on its behalf. Since there are no callbacks from the model to respond to (let's forget about "push" technologies for now), more business code is incorporated into the controller since it's the natural place to model business processes, though perhaps not validation.
In my understanding controllers in the web MVC pattern are just bridges between Models and Views, they simply grab the data from the Model and pass it on to the View. The Model and the View and independent and never talk to each other.
Question number three in my quest to properly understand MVC before I implement it:
I have two cases in mind:
The primary application
window needs to launch the
preferences window. (One View
invoking another View.)
The primary Model for an application
needs to access a property
in the preferences Model. (One Model
accessing another Model.)
These questions are related in that they both involve communication across Model-View-Controller triplets, a topic that I haven't found much discussion of in my Googling.
The obvious way to fix this is to wrap everything in a top-level "application" object that handles transactions between Models and allows Controllers to invoke one another's methods. I have seen this implemented, but I'm not convinced its a good idea. I can also see possibilities involving Controllers observing more than one Model and responding to more than one View, but this seems like its going to become very cluttered and difficult to follow.
Suggestions on how best to implement this sort of cross-talk? I feel like its a very obvious question, but I've been unable to find a well-documented solution.
On a broader note, if anyone has a link that shows typical approaches to these sorts of MVC issues, I would love to see it. I haven't had much luck finding solid, non-trivial references. Examples in Python would be lovely, but I'll gladly read anything.
Edit 1:
I see some pretty interesting things being said below and in general no-one seems to have a problem with the approach I've described. It is already almost a lazy form of the FrontController design that Vincent is describing. I certainly don't foresee any problems in implementing that pattern, however, it doesn't seem that anyone has really addressed the question in regards to communication amongst Models. All the answers seem to be addressing communication among objects in a single Model. I'm more interested in maintaining separate Models for separate components of the application, so that I'm not stuffing fifty state properties into a single Model class. Should I be maintaining them as sub-Models instead?
With respect to (1), views don't invoke other views. They invoke controller actions that may result in other views being rendered. In your case, the primary application window contains a user interface element (button, link) that invokes a controller action to display the preferences window.
With respect to (3), model components certainly could be related to one another. This isn't unexpected nor to be avoided, necessarily. For instance your Customer model may have an associated set of Orders. It would be perfectly natural to access the customer's orders via a method in the Customer class.
You might want to take a look at the MVC page on wikipedia for an overview.
You may want to consider looking up the Front Controller design pattern.
The Front Controller pattern defines a single component that is responsible for processing application requests. A front controller centralizes functions such as view selection, security, and templating, and applies them consistently across all pages or views. Consequently, when the behavior of these functions need to change, only a small part of the application needs to be changed: the controller and its helper classes.
This way all requests from the view goes to the FrontController who then decides which specific action (controller) to invoke. Sometimes, it could forward straight to another view as in your first case.
There is no problem with multiple objects in the model talking to each other. In fact that will be very common. The way I see it, all the objects in the Model act like one component to represent the data and operations on the data.
This article might help. And this one.
Model does not mean a single model object. The model is the subset of the entirety of your domain model which is directly related to the controller actions and the views in question.