AngularJS in practice

39
AngularJS in practice Eugene Fidelin © 2015 VNU Vacature Media Image by redbubble.com

Transcript of AngularJS in practice

AngularJS in

practiceEugene Fidelin © 2015VNU Vacature Media Image by redbubble.com

AngularJS fundamentals Let me show you some

pictures ...

Core objects and concepts

Module

The highest-level Angular object. Modules are how Angular packages its code.

An Angular app as specified by the ng-app directive always corresponds to a module.

Other objects are always created as children of modules.

http://paislee.io/a-conceptual-introduction-to-angularjs

DirectiveFilter

Config/Routes

Basically a container for app setup.

Within config it's typical to see routes configured. Routing is a pairing a view with a controller.

http://paislee.io/a-conceptual-introduction-to-angularjs

DirectiveFilter

Controller

Manages a special object called a scope that is accessible by the view that knows about that controller.

The controller is the gateway between the information that the view sees, and the logic that creates and works on that information.

http://paislee.io/a-conceptual-introduction-to-angularjs

DirectiveFilter

Factory/Service/Provider

Places where data processing should happen.

Each one is an Angular construct that simply wraps a different JavaScript approach to creating objects.

With factory any other construct could be created.

http://paislee.io/a-conceptual-introduction-to-angularjs

DirectiveFilter

Directive

The only place (besides the view) where DOM manipulations could be done.

Any time you find yourself repeating chunks of HTML, or referring to DOM nodes in JavaScript code, create a directive to encapsulate the output.

http://paislee.io/a-conceptual-introduction-to-angularjs

DirectiveFilter

Filter

Let you package the transformation of data in a way that's usable with the | syntax in the view.

For example, the expression 1408471200898 | date runs a timestamp through the built-in Angular date filter, outputting Aug 19, 2014.

http://paislee.io/a-conceptual-introduction-to-angularjs

DirectiveFilter

View

Is the Angular-flavored HTML.

$scope lives between the view and controller, and Angular is making sure both ends of the app have the latest version of it.

http://paislee.io/a-conceptual-introduction-to-angularjs

DirectiveFilter

MVC interaction

http://www.slideshare.net/kmstechnology/building-singlepage-web-applications-with-angularjs

$scope

Two-way binding

http://devgirl.org/2013/03/21/fun-with-angularjs

Dependency injection

Each component explicitly defined its dependencies.

Angular inject the requested dependency by the function argument names.

Once requested Angular’s injector instantiates the dependency and inject it.

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

angular.module('app')

.controller('MyController', function

($window, someOtherService) {

// ...

});

Bad practices I swear never to ...

Make code more complicated, less reusable and much harder to test.

Access or modify DOM in the controller

DOM should be changed only within the view (template) or directive.

Use in the controller scope variables defined in the view

These variables (usually it is either form or form element) should be explicitly passed to the controller methods.

Have business logic in the view

Views should have only render logic.

The rest should be either in the controller, filter or directive (if you need to use more than 1 time).

Expression in view should be as simple as possible.

Use jQuery

If you are using jQuery to manipulate DOM - you don’t need it. Angular has angular.element methods to manipulate the DOM in the directive code.

Any other functionality of jQuery has appropriate alternatives in Angular core or additional modules.

Perform HTTP requests in the controller

Controller should only use the services which encapsulate HTTP requests and provides methods to use them.

Put any logic in the application module run method

If you need something that is global for the whole application - create the service.

Use callbacks instead of promises

Promises are much easier to maintain and test - use them.

All asynchronous methods in Angular are returning promises, so you are already using them.

Use a scalar variable within an isolated scope

Isolated scopes are created by multiple directives.Updates from outside scopes won't appear inside after scalar variable is changed inside.Example: http://embed.plnkr.co/qRhLfw/preview

Note: using ControllerAs syntax solves the issue.

Good practices I’ll try my best to ...

Just make your life easier and application more

reliable

Separate the Angular and backend templates

Use as less as possible Angular directives in the backend templates.

ng-app and ng-controller to bootstrap Angular application and and ng-include to inject the Angular views.

Use ng-bind instead of {{}}

The {{}} are much slower.

ng-bind is a directive and it will only apply, when the passed value does actually change.

The brackets on the other hand will be dirty checked and refreshed in every $digest, even if it's not necessary.

Also, unrendered brackets are visible to the user, what required to use ng-cloak to hide them.

Use bind-once functionality

Angular allows to bind the value of an expression/attribute once (will be bound when != ’undefined’). This is useful, when value won’t be changed.

Place "::" before the binding to enable bind-once:

<p ng-bind=’::value’> or {{ ::value }}

Use ConrollerAs syntax

Controllers are more of a class based - all variables are assigned to this instead of $scope.

Controllers are namespaced in the views.

In details: Digging into Angular’s “Controller as” syntax

app.controller('MainCtrl', function () {

this.title = 'Some title';

});

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

{{ main.title }}

</div>

Build tools Grunt is our task runner, let’s see what plugins are used.

Help to write less code and keep it clean,

automate the process.

grunt-contrib-jshint

Detects errors and potential problems in JavaScript code.

It is very flexible and can be easily adjusted to particular coding guidelines and the environment where the code will be executed

grunt-contrib-concat

Concatenates multiple JavaScript files into one to speed up its downloading and page rendering.

Also allows to wrap code in the Immediately-Invoked Function Expression (IIFE) that prevents you code from leaking into the global scope.

grunt-ng-annotate

Adds and removes AngularJS dependency injection annotations. It is non-intrusive so the source code stays exactly the same otherwise.

Annotations are useful because with them it is possible to minify the source code.

grunt-angular-templates

Speed up the AngularJS app by automatically minifying, combining and caching HTML templates with $templateCache.

grunt-ng-constant

Separates code and configuration by dynamically generating Angular constant modules from the json and yaml configuration files.

grunt-contrib-uglify

Minifies and compress JavaScript files to minimize the size of files that must be downloaded and improve page performance.

Note: Angular dependency injection annotations should be added before uglifying.

Testing A developer is known by the tests he writes.

Angular is written with testability in mind, but it still requires that you

do the right thing.

Main tools

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.

Jasmine is a behavior driven development framework for JavaScript. Provides functions to help with structuring tests, making assertions and creating stubs (spies).

angular-mocks provides mocking for the tests. One of the most useful parts is $httpBackend, which allows to mock XHR requests in tests, and return sample data instead.

Unit tests

Angular comes with dependency injection built-in, which makes testing much easier, because you can pass in a component's dependencies and stub or mock them as you wish.

Test every controller, service or model in isolated environment by mocking all non-core dependencies (see Mocking Dependencies in AngularJS Tests)

Integration tests

Protractor is an end-to-end test framework for AngularJS applications. Protractor runs tests against your application running in a real browser, interacting with it as a user would.

● Guide to AngularJS Documentation

● AngularJS wiki

● A Conceptual Introduction to AngularJS

● Sane, scalable Angular apps are tricky, but not impossible. Lessons learned from PayPal Checkout.

● Mocking Dependencies in AngularJS Tests

Image by lifehack.org