Book Image

Mastering AngularJS for .NET Developers

By : Mohammad Wadood Majid, Golrokh Mirzaei
Book Image

Mastering AngularJS for .NET Developers

By: Mohammad Wadood Majid, Golrokh Mirzaei

Overview of this book

<p>AngularJS is an open source framework that utilizes the Model-View-Controller architecture for client-side application development. AngularJS is referred to as the Angular framework.</p> <p>With this book, you will soon be able to build client-side data driven applications. The introduction section covers the essentials of AngularJS, covering the core concepts of AngularJS to ensure a smooth transition to the more advanced topics discussed later on.</p> <p>This book covers the development of client-side applications with AngularJS using code examples before moving on to explore how to build the ASP.NET Web API and its features using Visual Studio .NET.</p>
Table of Contents (15 chapters)
Mastering AngularJS for .NET Developers
Credits
About the Authors
About the Reviewers
www.PacktPub.com
Preface
Index

Design and features of AngularJS 2.0


The current AngularJS framework design in an amalgamation of the changing Web and the general computing landscape; however, it still needs some changes. The current Angular 1.x framework cannot work with new web components, as it lends itself to mobile applications and pushes its own module and class API against the standards. To answer these issues, the AngularJS team is coming up with the AngularJS 2.0 framework. AngularJS 2.0 is a reimaging of AngularJS 1.x for the modern web browser.

The following are the changes in Angular 2.0:

AtScript

AtScript is a language used to develop AngularJS 2.0, which is a superset of ES6. It's managed by the Traceur compiler with ES6 to produce the ES5 code and it will use the TypeScript's syntax to generate runtime type proclamations instead of compile time checks. However, the developer will still be able to use the plain JavaScript (ES5) instead to using AtScript to write AngularJS 2.0 applications. The following is an example of an AtScript code:

import {Component} from 'angular';

import {server} from './server';

@Component({selector: 'test'}) 

export class MyNewComponent {

  constructor(serve:Server){
     this.sever=server
  }
}

In the preceding code, the import and the class come from ES6. There are constructor functions and a server parameter that specifies a type. In AtScript, this type is used to generate a runtime type assertion. The reference is stored, so that the dependency injection framework can use it. The @Component annotation is a metadata annotation. When we decorate some code within @Component, the compiler generates code that instantiates the annotation and stores it in a known location, so that it can be accessed by the AngularJS 2.0 framework.

Routing solution

In AngularJS 1.x, the routing was designed to handle a few simple cases. As the framework grew, more features were added to it. AngularJS 2.0 includes the following basic routing features, but will still be able to extend:

  • JSON route configuration

  • Optional convention over configuration

  • Static, parameterized, and splat route patterns

  • URL resolver

  • Query string

  • Push state or hash change

  • Navigation model

  • Document title updates

  • 404 route handling

  • Location service

  • History manipulation

  • Child router

  • Screen activate:

    • canActivate

    • activate

    • deactivate

Dependency Injection

The main feature of AngularJS 1.x was Dependency Injection (DI). It is very easy to used DI and follow the divide and conquer software development approach. In this way, the complex problems can be abstracted together and the applications that are developed in this way can be assembled at runtime with the use of DI. However, there are few issues in the AngularJS 1.x framework. First, the DI implementation was associated with minification; DI was dependent on parsing parameter names from functions, and whenever the names were changed, they were no longer matching with the services, controllers, and other components. Second, the missing features, which are more common to advance server-side DI features, are available in .NET and Java. These two features add constraints to scope control and child injectors.

Annotations

With the use of AtScript in the AngularJS 2.0 framework, a way to relate metadata with any function was introduced. The formatting data for metadata with AtScript is strong in the face of minification and is easy to write by pointer with ES5.

The instance scope

In the AngularJS framework 1.x, in the DI container, all the instances were singletons. The same is the case with AngularJS 2.0 by default. However, to get different behavior, we need to use services, providers, constants, and so on. The following code can be used to create a new instance every time the DI. It will become more useful if you create your own scope identifiers for use in the combination with child injectors, as shown:

@TransientScope

Export class MyClass{…} 

The child injector

The child injector is a major new feature in AngularJS 2.0. The child injector is inherited from its parent; however, the child injector has the ability to override the parents at the child level. Using this new feature, we can call certain type of objects in the application that will be automatically overridden in various scopes. For example, when a new route has a child route ability, each child route creates its own child injector. This allows each route to inherit from parent routes or to override those services during different navigation scenarios.

Data binding and templating

The data binding and template are considered a single unit while developing the application. In other words, the data binding and templates go hand in hand while writing an application with the AngularJS framework. When we bind the DOM, the HTML is handed to the template compiler. The compiler goes across the HTML to find out any directives, binding expressions, event handlers, and so on. All of the data is extracted from the DOM to data structures, which can be used to instantiate the template. During this phase, some processing is done on the data, for example, parsing the binding expression. Every node that contains the instructions is tagged with the class to cache the result of the process, so that work does not need to be repeated.

Dynamic loading

Dynamic loading was missing in AngularJS 1.x. It is very hard to add new directives or controllers at runtime. However, dynamic loading is added to Angular 2.0. Whenever any template is compiled, not only is the compiler provided with a template, but it is also provided with a component definition. The component definition contains metadata of directives, filters, and so on. This confirms that the necessary dependencies are loaded before the template gets managed by the compiler.

Directives

Directives in the AngularJS framework are meant to extend the HTML. In AngularJS 1.x, the Directive Definition Object (DDO) is used to create directives. In AngularJS 2.0, the directives are made simpler. There are three types of directives in AngularJS 2.0:

  • The component directive: This is a collection of a view and a controller to create custom components. It can be used as an HTML element as well as a router that can map routes to the components.

  • The decorator directive: Use this directive to decorate the HTML element with additional behavior, such as ng-show.

  • The template directive: This directive transforms HTML into a reusable template. The directive developer can control how the template is instantiated and inserted into the DOM, such as ng-if and ng-repeat.

The controller in AngularJS 2.0 is not a part of the component. However, the component contains the view and controller, where view is an HTML and controller is JavaScript. In AngularJS 2.0, the developer creates a class with some annotations, as shown in the following code:

@dirComponent({

Selector: 'divTabContainter'

Directives:[NgRepeat]

})

Export class TabContainer{

    constructor (panes:Query<Pane>){

    this.panes=panes
      }
select(selectPane:Pane){…}

}

In the preceding code, the controller of the component is a class. The dependencies are injected automatically into the constructor because the child injectors will be used. It can get access to any service up to the DOM hierarchy as well as it will local to service element. It can be seen in the preceding code that Query is injected. This is a special collection that is automatically synchronized with the child elements and lets us know when anything is added or removed.

Templates

In the preceding section, we created a dirTabContainer directive using AngularJS 2.0. The following code shows how to use the preceding directive in the DOM:

<template>

    <div class="border">

        <div class="tabs">

            <div [ng-repeat|pane]="panes" class="tab" 

(^click)="select(pane)">

                <img [src]="pane.icon"><span>${pane.name}</span>

            </div>

        </div>

        <content>
        </content>

    </div>
</template>

As you can see in the preceding code, in the <img [src]="pane.icon"><span>${pane.name}</span> image tag, the src attribute is surrounded with [], which tells us that the attribute has binding express. When we see ${}, it means that there is an expression that should be interpolated in the content. These bindings are unidirectional from the model or controller to the view. If you see div in the preceding <div [ng-repeat|pane]="panes" class="tab" (^click)="select(pane)"> template code, it is noticeable that ng-repeat is a template directive and is included with | and the pane word, where pane is the local variable. (^click) indicates that there is an event handler, where ^ means that the event is not a directory attached to the DOM, rather, we let it bubble and will be handled at the document level.

In the following code example, we will compare the code of the Angular framework 1.x and AngularJS 2.0; let's create a hello world example for this demonstration.

The following code is used to enable the write option in the AngularJS framework 1.x:

var module = angular.module("example", []);

module.controller("FormExample", function() {

  this.username = "World";

});

<div ng-controller="FormExample as ctrl">

  <input ng-model="ctrl.username"> Hello {{ctrl.username}}!

</div>

The preceding code example has been discussed throughout this book. A similar code can be written using AngularJS 2.0. The following code is used to write in the AngularJS framework 1.x:

@Component({

  selector: 'form-example'

})

@Template({

  // we are binding the input element to the control object
  // defined in the component's class 

  inline: '<input [control]="username">Hello 

          {{username.value}}!', directives: [forms]

})

class FormExample {

  constructor() {

    this.username = new Control('World');

  }

}

In the preceding code example, TypeScript 1.5 is used, which will support the metadata annotations. However, the preceding code can be written in the ES5/ES6 JavaScript. More information on annotations can be found in the annotation guide at https://docs.google.com/document/d/1uhs-a41dp2z0NLs-QiXYY-rqLGhgjmTf4iwBad2myzY/edit#heading=h.qbaubqkoiqds. Here are some explanations from TypeScript 1.5:

  • Form behavior cannot be unit tested without compiling the associated template. This is required because certain parts of the application behavior are contained in the template.

  • We want to enable the dynamically generated data-driven forms in AngularJS 2.0 although it is present in AngularJS 1.x. This is because in Angular 1.x, this is not easy.

  • The difficulty to reason your template statically arises because the ng-model directive was built using a generic two-way data binding.

  • An atomic form that can easily be validated or reverted to its original state is required, which is missing from AngularJS 1.x.

Although AngularJS 2.0 uses an extra level of indirection, it grants major benefits. The control object decouples form behavior from the template, so that you can test it in isolation. Tests are simpler to write and faster to execute.