Putting AngularJS in Context: Understanding the MVC Pattern

The term Model-View-Controller has been in use since the late 1970s and arose from the Smalltalk project at Xerox PARC where it was conceived as a way to organize some early GUI applications. Some of the fine detail of the original MVC pattern was tied to Smalltalk-specific concepts, such as screens and tools, but the broader ideas are still applicable to applications, and they are especially well-suited to web applications.

The MVC pattern first took hold in the server-side end of web development, through toolkits like Ruby on Rails and the ASP.NET MVC Framework. In recent years, the MVC pattern has been seen as a way to manage the growing richness and complexity of client-side web development as well, and it is in this environment that AngularJS has emerged.

The key to applying the MVC pattern is to implement the key premise of a separation of concerns, in which the data model in the application is decoupled from the business and presentation logic. In client-side web development, this means separating the data, the logic that operates on that data, and the HTML elements used to display the data. The result is a client-side application that is easier to develop, maintain, and test.

The three main building blocks are the model, the controller, and the view. In Figure 3-2, you can see the traditional exposition of the MVC pattern as it applies to server-side development.

I took this figure from my Pro ASP.NET MVC Framework book, which describes Microsoft’s server-side implementation of the MVC pattern. You can see that the expectation is that the model is obtained from a database and that the goal of the application is to service HTTP requests from the browser. This is the basis for round-trip web apps, which I described earlier.

Of course, AngularJS exists in the browser, which leads to a twist on the MVC theme, as illustrated in Figure 3-3

The client-side implementation of the MVC pattern gets its data from server-side components, usually via a RESTful web service, which I describe in Chapter 5. The goal of the controller and the view is to operate on the data in the model in order to perform DOM manipulation so as to create and manage HTML elements that the user can interact with. Those interactions are fed back to the controller, closing the loop to form an interactive application.

Tip Using an MVC framework like AngularJS in the client doesn’t preclude using a server-side MVC framework, but you’ll find that an AngularJS client takes on some of the complexity that would have otherwise existed at the server. This is generally a good thing because it offloads work from the server to the client, and that allows for more clients to be supported with less server capacity.

1. Understanding Models

Models—the Min MVC—contain the data that users work with. There are two broad types of model: view models, which represent just data passed from the controller to the view, and domain models, which contain the data in a business domain, along with the operations, transformations, and rules for creating, storing, and manipulating that data, collectively referred to as the model logic.

Tip Many developers new to the MVC pattern get confused with the idea of including logic in the data model, believing that the goal of the MVC pattern is to separate data from logic. This is a misapprehension: The goal of the MVC framework is to divide up an application into three functional areas, each of which may contain both logic and data. The goal isn’t to eliminate logic from the model. Rather, it is to ensure that the model contains logic only for creating and managing the model data.

You can’t read a definition of the MVC pattern without tripping over the word business, which is unfortunate because a lot of web development goes far beyond the line-of-business applications that led to this kind of terminology. Business applications are still a big chunk of the development world, however, and if you are writing, say, a sales accounting system, then your business domain would encompass the process related to sales accounting, and your domain model would contain the accounts data and the logic by which accounts are created, stored, and managed. If you are creating a cat video web site, then you still have a business domain; it is just that it might not fit within the structure of a corporation. Your domain model would contain the cat videos and the logic that will create, store, and manipulate those videos.

Many AngularJS models will effectively push the logic to the server side and invoke it via a RESTful web service because there is little support for data persistence within the browser and it is simply easier to get the data you require over Ajax. I describe the basic support that AngularJS provides for Ajax in Chapter 20 and for RESTful services in Chapter 21.

Tip There are client-side persistence APIs defined as part of the HTML5 standard effort. The quality of these standards is currently mixed, and the implementations vary in quality. The main problem, however, is that most users still rely on browsers that don’t implement the new APIs, and this is especially true in corporate environments, where Internet Explorer 6/7/8 are still widely used because of problems migrating line-of-business applications to standard versions of HTML.

For each component in the MVC pattern, I’ll describe what should and should not be included. The model in an application built using the MVC pattern should

  • Contain the domain data
  • Contain the logic for creating, managing, and modifying the domain data (even if that means executing remote logic via web services)
  • Provide a clean API that exposes the model data and operations on it

The model should not

  • Expose details of how the model data is obtained or managed (in other words, details of the data storage mechanism or the remote web service should not be exposed to controllers and views)
  • Contain logic that transforms the model based on user interaction (because this is the controller’s job)
  • Contain logic for displaying data to the user (this is the view’s job)

The benefits of ensuring that the model is isolated from the controller and views are that you can test your logic more easily (I describe AngularJS unit testing in Chapter 25) and that enhancing and maintaining the overall application is simpler and easier.

The best domain models contain the logic for getting and storing data persistently and for create, read, update, and delete operations (known collectively as CRUD). This can mean the model contains the logic directly, but more often the model will contain the logic for calling RESTful web services to invoke server-side database operations (which I demonstrate in Chapter 8 when I built a realistic AngularJS application and which I describe in detail in Chapter 21).

2. Understanding Controllers

Controllers are the connective tissue in an AngularJS web app, acting as conduits between the data model and views. Controllers add business domain logic (known as behaviors) to scopes, which are subsets of the model.

Tip Other MVC frameworks use slightly different terminology. So, for example, if you are an ASP.NET MVC Framework developer (my preferred server-side framework), then you will be familiar with the idea of action methods, rather than behaviors. The intent and effect are the same, however, and any MVC skills you have developed through server-side development will help you with AngularJS development.

A controller built using the MVC should

  • Contain the logic required to initialize the scope
  • Contain the logic/behaviors required by the view to present data from the scope
  • Contain the logic/behaviors required to update the scope based on user interaction

The controller should not

  • Contain logic that manipulates the DOM (that is the job of the view)
  • Contain logic that manages the persistence of data (that is the job of the model)
  • Manipulate data outside of the scope

From these lists, you can tell that scopes have a big impact on the way that controllers are defined and used. I describe scopes and controllers in detail in Chapter 13.

3. Understanding View Data

The domain model isn’t the only data in an AngularJS application. Controllers can create view data (also known as view model data or view models) to simplify the definition of views. View data is not persistent and is created either by synthesizing some aspect of the domain model data or in response to user interaction. You saw an example of view data in Chapter 2, when I used the ng-model directive to capture the text entered by the user in an input element. View data is usually created and accessed via the controller’s scope, as I describe in Chapter 13.

4. Understanding Views

AngularJS views are defined using HTML elements that are enhanced and that generate HTML by the use of data bindings and directives. It is the AngularJS directives that make views so flexible, and they transform HTML elements into the foundation for dynamic web apps. I explain data bindings in detail in Chapter 10 and describe how to use built-in and custom directives in Chapters 10-17. Views should

  • Contain the logic and markup required to present data to the user

Views should not

  • Contain complex logic (this is better placed in a controller)
  • Contain logic that creates, stores, or manipulates the domain model

Views can contain logic, but it should be simple and used sparingly. Putting anything but the simplest method calls or expressions in a view makes the overall application harder to test and maintain.

Source: Freeman Adam (2014), Pro AngularJS (Expert’s Voice in Web Development), Apress; 1st ed. edition.

Leave a Reply

Your email address will not be published. Required fields are marked *