Why AngularJS?
TODO:
What is the use case for this technology from the developers point of view
What benefit does a developer get from using this technology
What pain were we trying to solve by adopting this technology
What are the strengths and weaknesses of this technology
- STRENGTHS
- Two-way data binding
- HTML Templates
- Dependency Injection
- Deep Linking
- Directives!!!
- Testable
- Embeddable - you can attach the AngularJS application to a specific DOM element and not have to worry about nasty side effects outside of that element and into the rest of the page
What technologies complement this technology and can be used in tandem
How does it stand out from the crowd?
- Automatic refresh and the two-way data binding frees developers from the tedious work of explicitly triggering UI repaints
- Live DOM generated from HTML syntax is used as a templating language. More importantly, it is possible to extend an existing HTML vocabulary (by creating new directives), and then build UIs using a new HTML-based DSL
- Declarative approach to the UI results in a very concise and expressive way
- The excellent UI templating machinery doesn't put any constraints on the JavaScript code (for example, models and controllers can be created using plain, old JavaScript without the AngularJS APIs called all over the place)
Getting your development environment set up
TODO: add content here
Building
TODO: add content here
Testing
TODO: add content here
Best Practices
There are some great resources available on this topic already. Instead of duplicating all of them, here are some links to review.
- https://github.com/mgechev/angularjs-style-guide
- AngularJS Best Practices: I've Been Doing It Wrong! -- Part 1, Part 2, Part 3
- Unit Testing Best Practices in AngularJS
- Advanced Design Patterns and Best Practices
However, it does makes sense reiterate some of the most relevant ideas as well as a few that apply to Pentaho-specific development.
- If you find yourself manipulating DOM in a controller, STOP!!! DOM manipulation should really only be done in Directives and possibly in Filters.
- Keep Filters lean and mean. They get executed many times and can become a performance issue.
- Use angular-supplied versions of common javascript/jquery methods/objects
- Get to know the Angular API, don't rely on jQuery
- angular.copy
- angular.element
- angular.equals
- angular.extend
- angular.forEach
- angular.fromJson
- angular.identity
- angular.isArray
- angular.isDate
- angular.isDefined
- angular.isElement
- angular.isFunction
- angular.isNumber
- angular.isObject
- angular.isString
- angular.isUndefined
- angular.lowercase
- angular.noop
- angular.toJson
- angular.uppercase
App Structure
- Stick to the one file equals one AngularJS module principle. This will allow you to maintain relatively small, focused files and modules. Additionally you won't be concerned with the load order of those files. Also it will be possible to load individual modules under unit tests.
Data Binding
- Due to the nature of javascript itself and how it passes by value vs. reference, it's considered a best- practice in Angular to bind references in the views by an attribute on an object, rather than the raw object itself.
Controllers
- Create variables inside the controller to be explicit.
- It is considered a best-practice to name our controllers NameCtrl in camelcase.
- Keep controllers slim by using the dependency injection feature of AngularJS to access services.
Spreading route definitions among several modules
In a large scale web application, it is not uncommon to have dozens and dozens of different routes. While the $routeProvider service offers a very nice, fluent style API, route definitions can get quite verbose (especially when the resolve property is used). If we combine a large number of routes with the relative verboseness of each definition, we quickly end up maintaining a huge JavaScript file with several hundreds of lines of code! Worse yet, having all routes defined in one huge file means that this file must be modified quite frequently by all developers working on a project – a recipe for creating a bottlenecks and disastrous merge issues.
With AngularJS, we are not forced to define all the routes in one central file! If we take the approach of modularizing each functional area (has its own dedicated module), we can move routes linked to a certain part of an application to the corresponding module.
In the AngularJS module system, each and every module can have its associated config function, where we can inject $routeProvider service and define routes. For example: each of these submodules defines its own routes as follows:
angular.module('admin-users', []) .config(function ($routeProvider) { $routeProvider.when('/admin/users', {...}); $routeProvider.when('/admin/users/new', {...}); $routeProvider.when('/admin/users/:userId', {...}); }); angular.module('admin-projects', []) .config(function ($routeProvider) { $routeProvider.when('/admin/users', {...}); $routeProvider.when('/admin/users/new', {...}); $routeProvider.when('/admin/users/:userId', {...}); }); angular.module('admin', ['admin-projects', 'admin-users']);
Directives
- While declaring an AngularJS directive, the naming convention followed is camelCase. For example, we would define the name of the directive as 'myDatePicker'. But when you actually use the directive in your HTML, it is the dash-separated version (my-date-picker).
- To make your directives and attributes HTML5 compliant, you can prefix all AngularJS attributes with "data-" or "x-". That is, "x-ng-show" or "data-date-picker", and AngularJS will treat it just like you wrote it like a normal HTML element.
Plugging-In
TODO: add content here