Tiven Wang
chevron_rightAngular chevron_rightMVC

Angular.js 1.x Introduction

Wang Tiven November 22, 2016
425 favorite favorites
bookmark bookmark
share share

background

AngularJS is a structural framework for dynamic web apps. It lets you extend HTML’s syntax to express your application’s components in a clear and concise manner.

AngularJS is what HTML would have been, had it been designed for applications. It attempts to minimize the mismatch between document centric HTML and what an application needs by creating new HTML constructs.

AngularJS teaches the browser new syntax through constructs called directives. With the AngularJS framework you can build a versatile application using custom declarative elements with basic application features done for you out of the box.

Model View Controller(MVC) is a software design pattern for developing web applications. In this pattern, different features are broken into components to separate responsibilities. The model contains the data and logic, the view contains the visual layout and presentation, while the controller connects the two.

In AngularJS, the MVC pattern is implemented in JavaScript and HTML. The view is defined in HTML while the model and controller are implemented in JavaScript.

This tutorial focuses on AngularJS 1.x application codes and unit test.

The project code of this tutorial can be downloaded from Github

Application

This topic uses the latest Angular.js package ‘angular@1.5.8’

Scaffolding

Yeoman is a generic scaffolding system allowing the creation of any kind of app. Yeoman by itself doesn’t make any decisions. Every decision is made by generators which are basically plugins in the Yeoman environment.

Setting up Yeoman

npm install -g yo

Install Fountain Generator

npm i -g generator-fountain-webapp

Generate a web application step by step (generated project includes features: webpack, angular1, gulp, … you can find the details in file “.yo-rc.json” in project root)

yo fountain-webapp

Run

npm install -g gulp-cli

gulp serve start up the server for testing locally

gulp build and package the project codes into distribution.

How to cancel eslint syntax check: If you use Webpack, comment the preLoader part of the conf. If not, comment the eslint part of gulp_tasks/scripts.js.

Architectures

Project Architecture

The architecture of a angular.js project:

JavaScript-Project
|- conf/                        
|  |- gulp.conf.js            
|  |- karma.conf.js            
|  |- webpeak.conf.js
|  |- .../
|- dist/
|  |- index.html
|  |- vendor-xxxxxx.js
|  |- app-xxxxxx.js
|  |- index-xxxxxx.css
|  |- .../
|- gulp_tasks/
|- node_modules/
|  |- .../
|- src/
|  |- ../
|- .yo-rc.json
|- gulpfile.js
|- package.json
|/

Application Architecture

The architecture of an Angular.js application:

Angularjs-Application
|- app/                        
|  |- navigation.js
|  |- navigation.spec.js
|  |- login/
|  |  |- implicit-grant.html
|  |  |- implicit-grant.js
|  |  |- implicit-grant.spec.js
|  |  |- .../
|  |- .../
|- components/
|  |- message-component.js
|  |- message-component.spec.js
|  |- .../
|- services/
|  |- oauth2-service.js
|  |- oauth2-service.spec.js
|  |- .../
|- index.html
|- index.js
|- index.css
|- index.spec.js
|- .eslintrc.js
|/

Angularjs Codes

Require Angular Modules

Import angular modules into the application, then you can add the module dependencies into your angular module.

var angular = require('angular');
require('angular-route');
require('angular-resource');

Create an Angular Module

Create an Angular module and add it’s module dependencies

angular.module('app', ['ngRoute', 'ngResource'])

Create Angular Artifacts

Create independent files for every artifacts in Angular application, for example factory, service and controller. Then load them into an entry file using require.

var yaasOAuth2 = require('./services/yaas-oauth2');
...

angular
  .module(app, ['ngRoute', 'ngResource'])
  .factory('YaaSOAuth2', yaasOAuth2)

Controller

Controllers are the behavior behind the DOM elements. AngularJS lets you express the behavior in a clean readable form without the usual boilerplate of updating the DOM, registering callbacks or watching model changes.

Data-binding is an automatic way of updating the view whenever the model changes, as well as updating the model whenever the view changes. This is awesome because it eliminates DOM manipulation from the list of things you have to worry about.

Define a navigation controller

angularModule
  .controller('NavigationController', ['$scope', function($scope) {
    $scope.navigations = [
      {title: "implicit grant", url: "#/implicit-grant"},
      {title: "client credentials", url: "#/client-credentials"},
      {title: "password credentials", url: "#/password-credentials"}
    ];
  }]);

Use the controller in HTML, and add the Data-binding in the HTML elements, so you will obtain a navigation list

<body ng-app="app">
  <div ng-controller="NavigationController">
    <ul class="navigation">
      <li ng-repeat="navigation in navigations">
        <a href=""></a>
      </li>
    </ul>
  </div>
...

Reusable Components

A Component is a special kind of directive that uses a simpler configuration which is suitable for a component-based application structure.

angularModule
  .component('messageComponent', {
    template: require('./message-component.html'),
    controller: function MessageComponentController() {
      this.title = "This is response from YaaS server";
    },
    bindings: {
      message: '='
    }
  })

Use the component in the HTML, the variable response that passes value to the property message of messageComponent is from parent controller’s $scope

<h3>Response</h3>
<message-component message="response"></message-component>

Angular Services

Angular services are substitutable objects that are wired together using dependency injection (DI). You can use services to organize and share code across your app.

Angular services are:

  • Lazily instantiated – Angular only instantiates a service when an application component depends on it.
  • Singletons – Each component dependent on a service gets a reference to the single instance generated by the service factory.

Define the implementation of factory service that can be used by other controllers

angularModule
  .factory('YaaSOAuth2', ['$resource', function($resource) {
    return $resource('https://api.beta.yaas.io/hybris/oauth2/v1/token',
                      {},
                      {
                        authorize: {
                          method: 'POST',
                          headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
                          transformRequest : function(obj){
                            var str = [];
                            for(var p in obj)
                              str.push(encodeURIComponent(p) + "=" + encodeURIComponent(obj[p]));
                            return str.join("&");
                          }
                        }
                      }
                    );
  }]);

Use the service’s object in Controller

module.exports = ['$scope', 'YaaSOAuth2', function($scope, YaaSOAuth2) {
  ...

  YaaSOAuth2.authorize(credentials, function(response) {
    $scope.credentials = credentials;
    $scope.response = response;
  });
}];

Test

Karma is a JavaScript command line tool that can be used to spawn a web server which loads your application’s source code and executes your tests. You can configure Karma to run against a number of browsers, which is useful for being confident that your application works on all browsers you need to support. Karma is executed on the command line and will display the results of your tests on the command line once they have run in the browser.

Karma is a NodeJS application, and should be installed through npm. Full installation instructions are available on the Karma website. In this topic it has been integrated in fountain automatically.

Unit Test

Jasmine is a behavior driven development framework for JavaScript that has become the most popular choice for testing Angular applications. Jasmine provides functions to help with structuring your tests and also making assertions. As your tests grow, keeping them well structured and documented is vital, and Jasmine helps achieve this.

Define the unit test file ‘src/app/navigation.spec.js’

var angular = require('angular');
require('angular-mocks');
var Navigation = require('./navigation');

describe('navigation', function () {
  beforeEach(function () {
    angular
      .module('app', [])
      .controller('NavigationController', Navigation);
    angular.mock.module('app');
  });

  it('show the navigations in index', angular.mock.inject(function ($controller) {
    var $scope = {};
    $controller('NavigationController', {$scope: $scope});
    expect($scope.navigations.length).toEqual(3);
  }));
});

ESLint

ESLint is a tool for identifying and reporting on patterns found in ECMAScript/JavaScript code, with the goal of making code more consistent and avoiding bugs. It’s used in this project.

To change the rules in ESLint, you can modify the eslintConfig field in a package.json file or an .eslintrc.* file in your project.

Package & Deploy

Use the gulp command gulp default to clean and build the source codes into distribution folder.

Then you can deploy the application on to one of the Cloud Foundry servers.

Define the configuration file manifest.yml for cloud foundry

---
applications:
- name: <your-app-name>
  path: dist
  random-route: true
  memory: 64M

Login cloud foundry based server

$ cf login [-a API_URL] [-u USERNAME] [-p PASSWORD] [-o ORG] [-s SPACE]

Then use the command cf push to deploy the application.

References

Similar Posts

Comments

Back to Top