In AngularJS, it is easy to throw together a simple application and have it work. However, as the application grows in size and complexity, the code can easily become a confusing and cumbersome jumble of logic. To help prevent this situation, the roles and responsibilities of the controllers and views and their interaction with the scope and model should be revisited and clarified.
Let’s start with a few definitions provided by the Angular docs:
- View: what the user sees (the DOM)
- Controller: the business logic behind views
- Model: the data that is shown to the user and with which the user interacts
- Scope: context where the model is stored so that controllers, directives and expressions can access it
- Service: reusable business logic independent of views
So far there is nothing that surprising. However, reviewing the definitions side by side with your code can often reveal misplaced logic. Is the View trying to do more than just present the model? Is the controller manipulating the DOM or performing other presentation logic? How are the view and controller interacting with the scope?
Who's in control?
According to the Angular docs on controllers and Miško Hevery’s best practices presentation, the controller’s job is to support the view by presenting it with the data and logic that is necessary for it to do its job. This boils down to two jobs:
- Set up the initial state of the scope object.
- Add behavior to the scope object.
You might notice that both of these items write to the scope. That brings up a rule of thumb that Miško mentions: the scope should generally be treated as write-only by the controller and read-only by the view. So this is all well and good in theory but how do we put this knowledge to work? Let's say you end up with a view that looks something like this: Now, the view clearly shows that an element is conditionally visible and the controller is doing its job of supporting the view with business logic. As an added bonus, that logic is now also available to the controller's unit tests.
Model and Scope