AngularJS Part 1 - Mono · instantly reflected back to the Model ... • in AngularJS done via...

38
AngularJS Part 1 Jasmin , Software Architect Kristijan Horvat, Software Architect

Transcript of AngularJS Part 1 - Mono · instantly reflected back to the Model ... • in AngularJS done via...

Page 1: AngularJS Part 1 - Mono · instantly reflected back to the Model ... • in AngularJS done via arguments of a javascript function which creates an AngularJS element (Controller, Service,

AngularJS Part 1

Jasmin , Software Architect Kristijan Horvat, Software Architect

Page 2: AngularJS Part 1 - Mono · instantly reflected back to the Model ... • in AngularJS done via arguments of a javascript function which creates an AngularJS element (Controller, Service,

1 Intro to AngularJS

• client-side MVW JavaScript framework for writing compelling web applications

• built and maintained by Google • MVW stands for Model-View-Whatever, which gives us flexibility over design

patterns when developing applications - MVC (Model-View-Controller) or MVVM (Model-View-ViewModel) approach

• fully data-driven approach without needing to refresh Models, update the DOM and other time-consuming tasks such as browser bug fixes and inconsistencies

• focus is on the data, and the data takes care of the HTML, leaving us to programming our application

Page 3: AngularJS Part 1 - Mono · instantly reflected back to the Model ... • in AngularJS done via arguments of a javascript function which creates an AngularJS element (Controller, Service,

2 - Engineering concepts in JavaScript frameworks

• different approach on how AngularJS delivers data-binding and other engineering concepts than frameworks such as Backbone.js and Ember.js

• emphasis on the HTML everyone knows and loves, letting Angular hijack it and enhance it

• Angular keeps the DOM updated with any Model changes, which live in pure JavaScript Objects for data-binding purposes

Page 4: AngularJS Part 1 - Mono · instantly reflected back to the Model ... • in AngularJS done via arguments of a javascript function which creates an AngularJS element (Controller, Service,

2.1 - MVC and MVVM

• the goal is to eliminate problems like manually creating HTML piece by piece or manually updating HTML for a template when one little thing changes

• Angular provides proper separation of concerns, as well as dynamic HTML • data lives in a Model, HTML lives in a template to be rendered as a View,

and we use a Controller and a Scope (ViewModel) to connect the two, driving Model and View value changes

• MVVM is specifically targeted at user interface development • The View consists of the presentation layer, the ViewModel contains the

presentation logic and the Model contains our business logic and data

Page 5: AngularJS Part 1 - Mono · instantly reflected back to the Model ... • in AngularJS done via arguments of a javascript function which creates an AngularJS element (Controller, Service,

2.2 Two way data-binding

• concept which provides synchronization between Model and View layers

• model changes propagate to the View, and View changes are instantly reflected back to the Model

• plain old JavaScript Objects are used for binding as well as for communication with the server via a REST endpoint

• values are bound through Angular expressions (similar to handlebar templates) and ng-* prefixed attributes

Page 6: AngularJS Part 1 - Mono · instantly reflected back to the Model ... • in AngularJS done via arguments of a javascript function which creates an AngularJS element (Controller, Service,

2.3 Dependency Injection (DI)

• a software design pattern that deals with how components get hold of their dependencies

• an injection is the passing of a dependency to a dependent Object

• in AngularJS done via arguments of a javascript function which creates an AngularJS element (Controller, Service, Directive, etc.)

Page 7: AngularJS Part 1 - Mono · instantly reflected back to the Model ... • in AngularJS done via arguments of a javascript function which creates an AngularJS element (Controller, Service,

2.4 Single Page Applications (SPAs)

• all necessary code (HTML, CSS and JavaScript) is retrieved with a single page load or dynamically loaded

• The page does not reload at any point in the process, nor does control transfer to another page

• perception and navigability of separate logical pages in the application achieved via special technologies

• Interaction with the web server behind the scenes via AJAX and REST endpoint

• agnostic of server technology (.NET, PHP, etc.) • browser maintains the state of the application

Page 8: AngularJS Part 1 - Mono · instantly reflected back to the Model ... • in AngularJS done via arguments of a javascript function which creates an AngularJS element (Controller, Service,

3. Modules

• every application in Angular is created using modules

• a module can have dependencies of other modules, or be a single module all by itself

• modules act as containers for different sections of an application, making code more reusable and testable

Page 9: AngularJS Part 1 - Mono · instantly reflected back to the Model ... • in AngularJS done via arguments of a javascript function which creates an AngularJS element (Controller, Service,

3.1 Module definition (setter)

angular.module('app', []);

or with dependencies

angular.module('app', [

‘dependencyModule1’,

‘dependencyModule2’,

...

]);

Page 10: AngularJS Part 1 - Mono · instantly reflected back to the Model ... • in AngularJS done via arguments of a javascript function which creates an AngularJS element (Controller, Service,

3.2 Module initialization code

angular.module(myApp', []).

config(function(injectables) { // non instance injector

...configuration section, e.g. route configuration...

}).

run(function(injectables) { // instance injector

...run section, e.g. global events...

});

Page 11: AngularJS Part 1 - Mono · instantly reflected back to the Model ... • in AngularJS done via arguments of a javascript function which creates an AngularJS element (Controller, Service,

3.3 Module reference (getter)

for creating Angular elements (Controllers, Directives, Services, etc.), one needs to reference an existing module:

angular.module('app').controller(...)

Page 12: AngularJS Part 1 - Mono · instantly reflected back to the Model ... • in AngularJS done via arguments of a javascript function which creates an AngularJS element (Controller, Service,

3.4 HTML bootstrapping

to declare where AngularJS application sits in the DOM (typically the <html> or <body> elements), one needs to bind an ng-app attribute with the value of the root application module: <html ng-app="app">

...

</html>

AngularJS Sample #1 - Hello

Page 13: AngularJS Part 1 - Mono · instantly reflected back to the Model ... • in AngularJS done via arguments of a javascript function which creates an AngularJS element (Controller, Service,

4 Expressions

• Angular expressions are JavaScript-like code snippets that are usually placed in bindings such as {{ expression }}

• JavaScript expressions are evaluated against the global window, Angular expressions are evaluated against a $scope object

• In JavaScript, trying to evaluate undefined properties generates ReferenceError or TypeError. In Angular, expression evaluation is forgiving to undefined and null

• Conditionals, loops, exceptions, functions or regular expressions

• One-time binding with {{ ::expression }} for better performance

Page 14: AngularJS Part 1 - Mono · instantly reflected back to the Model ... • in AngularJS done via arguments of a javascript function which creates an AngularJS element (Controller, Service,

5 Controllers

• an Angular element that allows the interaction between a View and Model (i.e. HTML and JavaScript)

• a meeting place between the business logic and the presentational logic

• attached to a View via ng-controller attribute

• communicates with a View through $scope

Page 15: AngularJS Part 1 - Mono · instantly reflected back to the Model ... • in AngularJS done via arguments of a javascript function which creates an AngularJS element (Controller, Service,

5.1 Controller declaration

angular.module('app')

.controller('MainController', function (...DI...) {

...logic...

});

2 arguments: • name used in a ng-controller attribute • callback function which represents the controller declaration and holds all the

relevant logic AngularJS Sample #2 - Controller

Page 16: AngularJS Part 1 - Mono · instantly reflected back to the Model ... • in AngularJS done via arguments of a javascript function which creates an AngularJS element (Controller, Service,

5.2 Declaration syntax and minification

angular.module('myApp')

.controller('MainController', function ($scope, $timeout) {

...

});

vs angular.module('myApp')

.controller('MainController', ['$scope', '$timeout',

function ($scope, $timeout) {

...

}

]);

Page 17: AngularJS Part 1 - Mono · instantly reflected back to the Model ... • in AngularJS done via arguments of a javascript function which creates an AngularJS element (Controller, Service,

5.3 Controller as syntax

• available as of Angular v1.2 app.controller('MainController', function () {

this.title = 'Some title';

});

<div ng-controller="MainController as main">

{{ main.title }}

</div>

Page 18: AngularJS Part 1 - Mono · instantly reflected back to the Model ... • in AngularJS done via arguments of a javascript function which creates an AngularJS element (Controller, Service,

6 Understanding scope

• one of the most common concepts in any programming language (e.g. block scope, function scope, etc.)

• in AngularJS automated bridge between JavaScript and the DOM

• de facto a ViewModel

Page 19: AngularJS Part 1 - Mono · instantly reflected back to the Model ... • in AngularJS done via arguments of a javascript function which creates an AngularJS element (Controller, Service,

6.1 Scope prototypal inheritance

• angular behavior (ng-*) can be assigned to multiple DOM elements which creates a separate scope for each such assignment

• DOM parent/child hierarchy of assigned angular elements creates scope hierarchy

•inheritance

• there is a $rootScope which is not specific to any angular element, always exists and is at the top level of all created scopes

AngularJS Sample #3 - Scope

Page 20: AngularJS Part 1 - Mono · instantly reflected back to the Model ... • in AngularJS done via arguments of a javascript function which creates an AngularJS element (Controller, Service,

7 Filters

• Angular filters are a way of processing data and returning a specific set of it, against some kind of logic

• they can be used in two different ways: • in the DOM via a pipe | character inside expressions {{ filter_expression | filter : expression : comparator }}

• using the $filter Service, which can be injected via DI and used within JavaScript

$filter('filter')(array, expression, comparator);

Page 21: AngularJS Part 1 - Mono · instantly reflected back to the Model ... • in AngularJS done via arguments of a javascript function which creates an AngularJS element (Controller, Service,

7.1 Built-in filters

• currency

• number

• date

• json

• lowercase

• uppercase

• filter (array)

• limitTo (array)

• orderBy (array)

Page 22: AngularJS Part 1 - Mono · instantly reflected back to the Model ... • in AngularJS done via arguments of a javascript function which creates an AngularJS element (Controller, Service,

7.2 Custom filters

• single value filters • array filters • it is strongly discouraged to write filters that are stateful,

because the execution of those can't be optimized by Angular, which often leads to performance issues

AngularJS Sample #4 - Filters

Page 23: AngularJS Part 1 - Mono · instantly reflected back to the Model ... • in AngularJS done via arguments of a javascript function which creates an AngularJS element (Controller, Service,

8 Angular object types

• each web application is composed of objects that collaborate to get stuff done

• objects need to be instantiated and wired together for the app to work

• done automatically via Angular DI syntax or manually via $injector service

• two main types of objects - specialized objects and services

• an object is created with and belongs to a module

Page 24: AngularJS Part 1 - Mono · instantly reflected back to the Model ... • in AngularJS done via arguments of a javascript function which creates an AngularJS element (Controller, Service,

8.1 Angular objects DI

• each object has an identifier of the object and the description of how to create this object

• when an Angular application starts, Angular creates a new instance of injector, which in turn creates a registry of all objects defined in the core "ng" module, application module and its dependencies

Page 25: AngularJS Part 1 - Mono · instantly reflected back to the Model ... • in AngularJS done via arguments of a javascript function which creates an AngularJS element (Controller, Service,

8.2 Angular specialized objects

• conform to a specific Angular framework API

• Controllers

• Directives

• Filters

• Animations

Page 26: AngularJS Part 1 - Mono · instantly reflected back to the Model ... • in AngularJS done via arguments of a javascript function which creates an AngularJS element (Controller, Service,

8.3 Angular service objects

• logical components that contain application logic • built-in, e.g. $http for AJAX calls • custom, defined by the developer

• injector needs to know how to create these objects • done by registering a "recipe" for creating an object with the

injector • all services in Angular are singletons. That means that the

injector uses each recipe at most once to create the object. The injector then caches it for all future needs.

Page 27: AngularJS Part 1 - Mono · instantly reflected back to the Model ... • in AngularJS done via arguments of a javascript function which creates an AngularJS element (Controller, Service,

9. Angular service recipes

• Value

• Constant

• Factory

• Service

• Provider

Page 28: AngularJS Part 1 - Mono · instantly reflected back to the Model ... • in AngularJS done via arguments of a javascript function which creates an AngularJS element (Controller, Service,

9.1 Value recipe

• any kind of a constant like string, number, date-time, array, object or even a function

var myApp = angular.module('myApp', []);

myApp.value('appTitle', 'My Angular Application');

myApp.controller('MainController', ['$scope', 'appTitle'

function ($scope, appTitle) {

$scope.appTitleText = appTitle;

}

]);

Page 29: AngularJS Part 1 - Mono · instantly reflected back to the Model ... • in AngularJS done via arguments of a javascript function which creates an AngularJS element (Controller, Service,

9.2 Constant recipe

• same as value, but can also be injected to a module configuration

var myApp = angular.module('myApp', []);

myApp.constant('configConstant', { x: 1, y: 2 });

myApp.config(['configConstant',

function (configConstant) {

... configConstant.x ...

}

]);

Page 30: AngularJS Part 1 - Mono · instantly reflected back to the Model ... • in AngularJS done via arguments of a javascript function which creates an AngularJS element (Controller, Service,

9.3 Factory recipe

• more powerful than value recipe

• aside from plain constants can return • a constant which is a result of some logic

• a JavaScript function to be instantiated (~ a class)

• a created JavaScript object (~ an instance of a class)

• ability to use other services (have dependencies)

Page 31: AngularJS Part 1 - Mono · instantly reflected back to the Model ... • in AngularJS done via arguments of a javascript function which creates an AngularJS element (Controller, Service,

9.3 Factory recipe

var myApp = angular.module('myApp', []);

myApp.value('factor', 5);

myApp.factory('square', ['factor', function(factor) {

return factor * factor;

}]);

myApp.controller('MainController', [‘$scope’, ‘square’,

function ($scope, square) {

$scope.product = square;

}

]);

Page 32: AngularJS Part 1 - Mono · instantly reflected back to the Model ... • in AngularJS done via arguments of a javascript function which creates an AngularJS element (Controller, Service,

9.3 Factory recipe

function UnicornLauncher(apiToken) { this.launchedCount = 0; this.launch = function() { // Make a request to the remote API and include the apiToken... this.launchedCount++; } } myApp.factory('unicornLauncher', ['apiToken', function(apiToken) { return new UnicornLauncher(apiToken); }]);

Page 33: AngularJS Part 1 - Mono · instantly reflected back to the Model ... • in AngularJS done via arguments of a javascript function which creates an AngularJS element (Controller, Service,

9.4 Service recipe

• produces a service just like the Value or Factory recipes, but it does so by invoking a constructor with the new operator

• the constructor can take zero or more arguments, which represent dependencies needed by the instance of this type

• a design pattern called constructor injection

Page 34: AngularJS Part 1 - Mono · instantly reflected back to the Model ... • in AngularJS done via arguments of a javascript function which creates an AngularJS element (Controller, Service,

9.4 Service recipe

myApp.service('unicornLauncher', ['apiToken', UnicornLauncher]);

OR myApp.service('unicornLauncher', ['apiToken', function (apiToken) {

this.launchedCount = 0;

this.launch = function() {

// Make a request to the remote API and include the apiToken...

this.launchedCount++;

}

}]);

Page 35: AngularJS Part 1 - Mono · instantly reflected back to the Model ... • in AngularJS done via arguments of a javascript function which creates an AngularJS element (Controller, Service,

9.5 Provider recipe

• core recipe type • other recipe types are just syntactic sugar on top of it • defined as a custom type that implements a $get

method (a factory function) • use the Provider recipe only when you want to expose

an API for application-wide configuration that must be made before the application starts (e.g. debug vs release app configuration)

Page 36: AngularJS Part 1 - Mono · instantly reflected back to the Model ... • in AngularJS done via arguments of a javascript function which creates an AngularJS element (Controller, Service,

9.5 Provider recipe

myApp.provider('unicornLauncher', function UnicornLauncherProvider() {

var useTinfoilShielding = false;

this.useTinfoilShielding = function(value) {

useTinfoilShielding = !!value;

};

this.$get = ['apiToken', function unicornLauncherFactory(apiToken) {

return new UnicornLauncher(apiToken, useTinfoilShielding);

}];

});

myApp.config(['unicornLauncherProvider', function(unicornLauncherProvider) {

unicornLauncherProvider.useTinfoilShielding(true);

}]);

Page 37: AngularJS Part 1 - Mono · instantly reflected back to the Model ... • in AngularJS done via arguments of a javascript function which creates an AngularJS element (Controller, Service,

9.6 A word about naming conventions

• use PascalCase for functions which return a constructor function that's supposed to be newed, e.g. var user = new User()

• use PascalCase for controllers which are viewed in Angular as scope constructor functions

• use camelCase for everything else