In AngularJS applications, view is the Document Object Model (DOM), controllers are the JavaScript functions, and the model data keeps object properties. We need to understand that MVC is needed for many reasons. First, it offers you a mental model for where to place what; therefore, you do not need to invent it each time. Other people collaborating on your project will take a moment to understand what you've written, as they may perceive that you have victimized the MVC structure because you have added your code. Maybe most significantly, we'll claim that it delivers nice edges in creating your app easier to grow, maintain, and test.
AngularJS is constructed around the belief that declarative programming ought to be used to build user interfaces and wire software package components, whereas imperative programming is great for expressing business logic. The framework adapts and extends ancient HTML to raise and serve dynamic content through two-way data binding that permits the automated synchronization of models and views. As a result, AngularJS de-emphasizes DOM's manipulation and improves its testability and performance.
Separation of the HTML DOM (view) from the application logic (controller) improves the testability of the code in the following way:
A typical collaboration of the MVC elements is shown in the following figure:
The MVC pattern brings modularity to application developers and it enables:
When we quote views and controllers, their possession itself explains the separation. The views are simply the presentation type of the associate application; it doesn't have to be compelled to specifically concerning the requests that return from the controller. The model is independent of view and controllers; it solely holds the business entities that will be passed to any view by the controller, as required, for exposing them to the end user. The controller is independent of views and models. Its sole purpose is to handle requests and to pass them on as per the routes outlined and as per the necessity of the rendering views. Therefore, our business entities (model), business logic (controller), and presentation logic (view) layers are independent of every alternative.
The model is where the application's data objects are stored. The model doesn't apprehend anything regarding views and controllers. Once a model changes, usually it will give its observers notice that a modification has occurred. A model contains data that represents this state during the application's lifecycle. The model doesn't have direct access to the view or controller. Any modification within the model gets transmitted to the view through the controller. This allows the model to be separated from the view and controller, which helps reusability and quantifiability of the code. We will use an identical model to transmit data to totally different views throughout an application's data request. Views show this data. Controllers manage the link between your model and your views. Models store data, which is often dynamic data from a database; otherwise, you can even get data from a static JSON file, which is the business entity on which the general application operates. Several applications use a persistent storage mechanism (such as a database) to store data. MVC doesn't specifically mention the data access layer; as a result, it's encapsulated by the model. The following is the code example of the JSON data:
$scope.meal= { 'breakfast' : 'Orange Juice', 'Lunch' : 'Fruit Salad', 'Dinner' : 'Vegetable Rice' }
A view is what's bestowed on the users and the way users interact with the application. The view is formed with HTML, CSS, JavaScript, and other templates. Views show a model's information by using double curly brackets to bind expressions to elements, as shown in the following example. A view would get information from the meal variable that holds the JSON data for breakfast. The code example for view is as follows:
<h1> {{meal.breakfast}} </h1>
The controller is the decision maker and also the glue between a model and view. The controller updates the view when the model changes. Additionally, it adds event listeners to the view and updates the model when the user manipulates the view. Controllers can be used to manage a model and data can be retrieved as well as flaunted to the end user. Wrap the model during a controller function, as shown in the following example:
var app = angular.module('myApp'), app.controller('ctrlFood', function ($scope) { } <div ng-controller = "ctrlFood"></div>
A div
tag holds a controller
directive. Note that ctrlFood
in ng-controller= "ctrlFood"
is same as the function name.
AngularJS looks like a traditional markup language with some new markup features that are known as templates. Once an AngularJS template starts the application, it parses and processes this new markup from the markup language (template). The markup is named as directives and we'll discuss this in detail in Chapter 2, Learning AngularJS Binding and Directives. Directives apply special behavior to markup language components. As an example, the ng-app
attribute is coupled with a directive that mechanically initializes the application. AngularJS additionally defines a directive for the input components that add additional behavior to the element. As an example, the ng-model
directive stores or updates the value of the input element.
Another reasonable markup utilized in HTML is the double curly braces filter. Once the page is loaded and it is encountered with this markup, it'll be replaced with the evaluated value of the markup. An expression in HTML may be a JavaScript-like code snippet that permits reading and writing of the variables. These variables don't seem to be global variables. AngularJS provides a scope, which is an object that refers to the application model. It's an execution context for expressions. Scopes are organized in gradable structures that mimic the DOM structure of the application. The markup additionally contains a filter; a filter formats the value of an expression in order to display it for the user. They will be utilized in view templates, controllers, or services, and it's a straightforward task to define your own filter. The vital issue is that AngularJS provides live bindings. Whenever the input values are modified, the values of the expressions are automatically recalculated and the DOM is updated with their values. The construct behind this is often the two-way data binding that we are going to discuss intimately in Chapter 2, Learning AngularJS Binding and Directives.
An example code for a web page that takes your name and favorite car as input and then displays it to the reader with a counter for the car is shown as follows:
<html ng-app="myApp"> <head> <script src="angular.js"></script> <script src="AngularControllers.js"></script> </head> <body> <h1><u>Mastering AngularJS for .Net Developer</u></h1> <div ng-controller="myController"> <label>Name:</label> <inputtype="text"placeholder="Please enter name"ng-model="name"> <h4ng-show="name">Hello! <b>{{name}}</b> select your favorite car from dropdown</h4> <selectng-model="selectedCar"ng-change="onCarSelectionChanged()"> <optionvalue="">Please select car</option> <option>Audi</option> <option>BMW</option> <option>Mercedes-Benz</option> <option>Porsche</option> <option>Volkswagen</option> </select> <h3ng-show="selectedCar"> <span style="font-weight:normal">{{name}} your favorite car is <b>{{selectedCar}}</b></span> </h3> <spanng-show="countCarSelectionChanged> 0">You change your favorite car {{countCarSelectionChanged}} times. </span> </div> </body> </html>
Our logic for AngularControllers.js
is as follows:
var app = angular.module('myApp', []); app.controller("myController", function ($scope) { $scope.countCarSelectionChanged = 0; $scope.onCarSelectionChanged = function () { $scope.countCarSelectionChanged++; }; });
Downloading the example code
You can download the example code files from your account at http://www.packtpub.com for all the Packt Publishing books you have purchased. If you purchased this book elsewhere, you can visit http://www.packtpub.com/support and register to have the files e-mailed directly to you.
Loading index.html
into a browser will then produce what you see in the following screenshot:
There are a few interesting things to note here:
myController
class could be a plain JavaScript class and it doesn't inherit from something that AngularJS provides. It must be registered with AngularJS.myController
class has got the $scope
object that it needed without having to create it.myController
class's constructor ourselves or figure out when to call it.CarSelectionChanged
is called using the ng-change
directive, it will set the count of your favorite car, which was selected. We didn't have to register any event listeners or write any callbacks.In the preceding code example, to select your favorite car as input in line 1, AngularJS specifies the distinctive HTML attribute, ng-app
. This attribute sets the boundaries of the application and is applied on any HTML element within that boundary. The ng-app
attribute within the HTML tag is the AngularJS application root element. AngularJS will parse the markup delimited by the application root element and look for any ng-
prefixed elements, attributes, or CSS classes. It will match some regular HTML tags, such as input, and select them if they contain the ng-
prefixed attributes or CSS classes. These entities will then be mapped to the instances of special AngularJS directives.
The directives are accustomed to adding dynamic behavior to HTML content and introducing a strong, useful, and declarative user interface definition language. All HTML components in an AngularJS application will be related to at least one instance of a scope. A scope links the view
, by
HTML elements to the code behind the view and during this example by directives. The scope object is initialized and owned by AngularJS components, and also, the view solely references properties and functions of the scope object. The applying root elements will be related to the initial scope of the application. This primary scope is named the root scope, and any AngularJS application can have a minimum of one scope, which is the instance of the root scope.
In the preceding example, ng-controller
introduces a directive that maps an AngularJS object called controller to the HTML section delimited by the current element. The controller is defined in the AngularControllers.js
script, which is a globally accessible function. We call this function the controller constructor function. Note that the $scope
parameter represents the current scope instance. This parameter gets initialized automatically by AngularJS; so, when the controller constructor function is executed, the scope is available and ready to use. Declaring a parameter in a component definition and expecting AngularJS to automatically provide it is the signature of the dependency injection mechanism. The controller will be discussed in Chapter 2, Learning AngularJS Binding and Directives.
The scope passed to the controller is also attached to the view represented by the HTML element with the ng-controller
attribute. The controller and view share data through the model represented by the scope instance. Any property defined on the controller scope will also be visible to the HTML view.
In the preceding example, the <input>
HTML element used the ng-model="name"
directive, which holds the value of the <input>
element. Another directive, ng-show="name"
is used in the <h4>
HTML element, which will show the <h4>
element as soon as the user starts typing in the <input>
element. The <h4>
element will show the value of the ng-model
of the <input>
HTML element using {{name}}
in <h4>
.
The controller name, myController
is declared and the $scope
parameter is injected in the controller, as shown in AngularControllers.js
. We will explain line 1 of the code file later in this book. This example also illustrates the first property, carChangedCount
of the controller. The initially assigned value to carChangedCount
is zero. The onCarSelectionChanged
property is used to declare a function. This function will increment the first property, carChangedCount
by 1 when it is called.
The onCarSelectionChanged
property will evaluate the expression value of the attribute every time the selection changes. We can see that it is called in the example in the <select>
element of HTML. The <select>
element also uses the ng-model="selectedCar"
directive, which will hold the value of a user's selection from the drop-down list. Another directive, ng-show
is also used. This directive will show the {{name}}
text your favorite cars, <b>{{selectedCar}}</b>
. Here, {{name}}
and {{selectedCar}}
are the values from the <input>
element and the <select>
elements of HTML.
The ng-show
directive is used with a condition. It will show the value of the countCarSelectionChanged
model property if it is greater than 0
.
The following figure shows the data flow of the preceding code example:
The following is a description of how AngularJS interacts with browsers:
angular.js
scriptDOMContentLoaded
eventng-app
directive, which designates the application boundaryng-app
(if any) is used to configure $injector
ng-init
directive assigns a value to the name
property on the scope{{name}}
property interpolates the expression to the applicationAngularJS directives enable developers to specify custom and reusable hypertext markup language tags that moderate the behavior of certain elements. Some of the directives are as follows: