AngularJs Crash Course

7,195
-1

Published on

An introduction to the complex single page web application framework known as AngularJs. An attempt to overview the high-level aspects of the framework, and to supply references for further exploration.

Published in: Technology
1 Comment
36 Likes
Statistics
Notes
  • I may need to pull this presentation soon or update as the parts are changing quickly. For example: ng-min has been deprecated in favor of ng-annotate, Protractor/e2e tasks can be more easily assembled, controllers may go away entirely, Gulp has gained favor over Grunt as a build tool...
       Reply 
    Are you sure you want to  Yes  No
    Your message goes here
No Downloads
Views
Total Views
7,195
On Slideshare
0
From Embeds
0
Number of Embeds
2
Actions
Shares
0
Downloads
708
Comments
1
Likes
36
Embeds 0
No embeds

No notes for slide

AngularJs Crash Course

  1. 1. Crash Course Keith Bloomfield Lead Developer dev9
  2. 2. Crash CourseCrash Course Show of Hands Front-end developers? Back-end developers? Other? Using AngularJs at work/home? New to AngularJs? Keith Bloomfield Lead Developer dev9
  3. 3. Overview Data Binding, Expressions, Scopes, Ng Directives Modules, Dependency Injection Controllers, Services, Factories, Directives Unit Testing End-to-End (e2e) Testing Continuous Integration Real World Experiences Tool Support Resources for Learning Q&A Crash Course Agenda
  4. 4. Overview ● AngularJs is a Spa framework ● Manicure/Pedicure ● Body/Facial Treatment ● Massage ● A lot has changed on the front-end in the last few years!
  5. 5. Overview ● AngularJs is a Spa framework ● Single-Page Application (dynamic views) ● Recommends client-side Model-View-Controller (Mvc) pattern
  6. 6. Overview ● AngularJs is a Spa framework ● Single-Page Application (dynamic views) ● Recommends client-side Model-View-Controller (Mvc) pattern Don't know about each other.
  7. 7. Overview ● AngularJs is a Spa framework ● Single-Page Application (dynamic views) ● Recommends client-side Model-View-Controller (Mvc) pattern
  8. 8. Overview ● AngularJs is a Spa framework ● Single-Page Application (dynamic views) ● Recommends client-side Model-View-Controller (Mvc) pattern Implications: Routing History Caching Packaging Deployment Automation Data Binding Object Modeling Timing/Dispatch Templating Testing Storage ... AngularJs
  9. 9. Overview ● AngularJs is a Spa framework ● Single-Page Application (dynamic views) ● Recommends client-side Model-View-Controller (Mvc) pattern What becomes of this?
  10. 10. Overview ● AngularJs is a Spa framework ● Single-Page Application (dynamic views) ● Recommends client-side Model-View-Controller (Mvc) pattern Model-View-Whatever (Mvw)
  11. 11. The View ● Templates/Partials foo.html Html content swapped into/out of the single page my-app.html my-header.html my-cart.html my-news.htmla2.htmla2.html bn.html c1.html a1.html a3.html b3.html b2.htmlb1.html c2.html d.html my-mail.html my-tools.html
  12. 12. Data Binding, Expressions and Scopes ● Extending Html's vocabulary: Directives – Extend Html as markers on the Dom – Can be used as an attribute, element, class name, comment – Tell AngularJs' compiler ($compile) to attach specific behavior to that Dom element or even transform that element and its children. <!DOCTYPE html> <html ng-app> <head> <title>echo</title> </head> <body> <div class="container"> Name: <input type="text" ng-model="echo"/> <br/> {{ echo }} </div> <script src="scripts/angular.min.js"></script> </body> </html> Angular (ng) Directives Data Binding Expression “The compilation is a process of walking the DOM tree and matching DOM elements to directives.” (links scope to template) auto-bootstraps the AngularJs application/ designates the root element. binds input, select, textarea to a property on the scope using ng-model (NgModelController), and more. Evaluated against the scope.
  13. 13. Data Binding, Expressions and Scopes ● Extending Html's vocabulary: Directives – Extend Html as markers on the Dom – Can be used as an attribute, element, class name, comment – Tell AngularJs' compiler ($compile) to attach specific behavior to that Dom element or even transform that element and its children.
  14. 14. Data Binding, Expressions and Scopes ● Extending Html's vocabulary: Directives ● The only place where an AngularJs application touches the Dom is within directives. ● This is good as artifacts that access the Dom are difficult to test. More about directives later, but first...
  15. 15. Data Binding, Expressions and Scopes ● $scope ● Acts as the glue between the view and the controller ● Refers to the application model ● Arranged hierarchically to mimic the Dom ● Can inherit from parent scope ● Can watch expressions and propagate events
  16. 16. Data Binding, Expressions and Scopes ● $scope ● $rootScope: Defined at the top level of the application (where the ng-app directive is applied) ● Lookup proceeds up the scope chain when a variable is not found in the local scope. ● Relying on scope is risky because the Dom layout is often changed. - Isolating scope protects against changes to the Dom hierarchy.
  17. 17. Data Binding, Expressions and Scopes ● $scope ● $watch: Observe model mutations ● $apply: Propagate model changes through the system into the view from outside the Angular realm (controllers, services, ng event handlers). Triggers $digest, which can be used directly in unit tests. ● Also available: $watchCollection, $destroy, $eval, $evalAsync, $on, $emit, $broadcast
  18. 18. Dependency Injection ● Reusable container for different features of your app Module
  19. 19. Dependency Injection ● Has two phases: – config: setup providers and constants – run: after injector is created, kickstart the app angular.module('myModule', ['moduleDependency1', 'moduleDependency2',....]) .config(function(injectable1, injectable2,...) { // provider-injector // Use as many of these as you want. // Can only inject Providers (not instances) }) .run(function(injectable1, injectable2,....) { // instance-injector // Use as many of these as you want. // Can only inject instances (not Providers) and constants }); Module
  20. 20. Dependency Injection Module ● Features can be bundled and injected in/as modules
  21. 21. Dependency Injection ● $provide - Object in module auto ● auto - Implicit module which gets automatically added to each $injector ● $injector - used to retrieve object instances as defined by provider, instantiate types, invoke methods, and load modules.
  22. 22. Dependency Injection ● $provide - Helper methods (also exposed on module): ● provider(provider) - registers a service provider with the $injector ● constant(obj) - registers a value/object that can be accessed by providers and services. ● value(obj) - registers a value/object that can only be accessed by services, not providers. ● factory(fn) - registers a service factory function, fn, that will be wrapped in a service provider object, whose $get property will contain the given factory function. ● service(class) - registers a constructor function, class that will be wrapped in a service provider object, whose $get property will instantiate a new object using the given constructor function. ● Worth investigating: $provide.decorator() // $provide only https://egghead.io/lessons/angularjs-provide-decorator
  23. 23. Dependency Injection ● $provide - Helper methods (also exposed on module): ● provider(provider) - registers a service provider with the $injector ● constant(obj) - registers a value/object that can be accessed by providers and services. ● value(obj) - registers a value/object that can only be accessed by services, not providers. ● factory(fn) - registers a service factory function, fn, that will be wrapped in a service provider object, whose $get property will contain the given factory function. ● service(class) - registers a constructor function, class that will be wrapped in a service provider object, whose $get property will instantiate a new object using the given constructor function. “Where is the Controller?” ● Added to the Dom using ng-controller ● The ng-controller directive asks the injector to create an instance of the controller and its dependencies. ● The controller itself never knows about the injector. ● Loose coupling is maintained.
  24. 24. Dependency Injection ● Dependencies are looked up by name for a provider that satisfies the argument. app.controller(“AController”, function($scope, $http){ $scope.userName = 'Walt'; $scope.foo = $http.get('http://foo.com'); }); a.controller(“AController”, function(b, c){ b.userName = 'Walt'; b.foo = c.get('http://foo.com'); }); ● Minified: Order doesn't matter $scope found in ng module - $rootScopeProvider - $rootScope.Scope $http service found ng module - $http OH NO!
  25. 25. Dependency Injection ● Longer version preserves dependency by treating it as an argument: app.controller(“AController”, ['$scope', '$http', function($scope){ $scope.userName = 'Walt'; $scope.foo = $http.get('http://foo.com'); }]); a.controller(“AController”, ['$scope', '$http', function(b, c){ b.userName = 'Walt'; b.foo = c.get('http://foo.com'); }]); ● Minified: Order matters Passed in as arguments to the function
  26. 26. Dependency Injection ● Minification Pain Relief: ngmin https://github.com/btford/ngmin It turns this angular.module('whatever').controller('MyCtrl', function ($scope, $http) { ... }); into this angular.module('whatever').controller('MyCtrl', ['$scope', '$http', function ($scope, $http) { ... }]);
  27. 27. Controllers ● Used to augment the Angular scope ● Attached to the Dom via the ng-controller directive ● Set up the initial state of the $scope object ● Add behavior to the $scope object <html ng-app="pizza-shop"> <head></head> <body ng-controller="HomeController"> <div class="container"> <header ng-include="'templates/header.html'"> </header> <h2>Our Pizzas:</h2> <div ng-repeat="pizza in pizzas"> <h3>{{ pizza.name }}</h3> ... app.controller('HomeController', function($scope){ $scope.pizzas = [ { name: "Meat Lover's", ingredients: ['Sausage','Pepperoni','Bacon','Olives'], price: 6 }, { name: 'Hawaiian', ingredients: ['Canadian bacon','Pineapple'], price: 5 }, ]; });
  28. 28. !Controllers ● Do not use a controller to: ● Manipulate the Dom - Business logic only. Presentation logic affects testability and belongs in directives ● Format input - Use angular form controls instead: https://docs.angularjs.org/guide/forms ● Filter output - Use angular filters instead: https://docs.angularjs.org/guide/filter ● Share code or state across controllers - Use angular services instead: https://docs.angularjs.org/guide/services ● Manage the life cycle of other components - eg: Using a controller to create a service instance
  29. 29. Services ● Stateless, injectable argument providing the instance of a function passed to module.service ● Singleton: delayed/lazy loaded (Not instantiated until used), only instantiated once ● Good for cross app/controller communication (sharing of utility functions) service(class) - registers a constructor function, class that will be wrapped in a service provider object, whose $get property will instantiate a new object using the given constructor function.
  30. 30. Factories service factory module.service('MyService', function() { this.method1 = function() { //.. } this.method2 = function() { //.. } }); module.factory('MyService', function() { var factory = {}; factory.method1 = function() { //.. } factory.method2 = function() { //.. } return factory; }); factory(fn) - registers a service factory function, fn, that will be wrapped in a service provider object, whose $get property will contain the given factory function.
  31. 31. Services, Factories, Values, Constants ● Are convenience methods for making providers ● Serve to avoid polluting the global namespace
  32. 32. Services, Factories, Values, Constants ● The difference between factory and service is the difference between a function and an object. ● Factory(give it a function) ● Service(give it a constructor) ● Further study (object vs. function): http://stackoverflow.com/questions/1646698/what-is-the-new-keyword-in-javascript ● Further study (ng factory vs. service): http://iffycan.blogspot.com/2013/05/angular-service-or-factory.html https://www.youtube.com/watch?v=A6cJasNBkyI service vs. factory
  33. 33. Services, Factories, Values, Constants ● Either can be a primitive, object, or function ● Constant can be injected into services, controllers, or module configs ● Value can only be injected into services and controllers value vs. constant “Why can't value be injected into module config?” The injector has not been setup yet. Constants (special case) are accessed by their name alone, cannot be changed, and aren't accessed through a provider $get.
  34. 34. Services, Factories, Values, Constants ● Are convenience methods for making providers You can also create your own providers: app.config(function($provide){ $provide.provider('MyProvider',{ $get: function(){ return{ foo: function(){ return 'bar'; } } } }) });
  35. 35. Services, Factories, Values, Constants function provider(name, provider_) { assertNotHasOwnProperty(name, 'service'); if (isFunction(provider_) || isArray(provider_)) { provider_ = providerInjector.instantiate(provider_); } if (!provider_.$get) { throw $injectorMinErr('pget', "Provider '{0}' must define $get factory method.", name); } return providerCache[name + providerSuffix] = provider_; } function factory(name, factoryFn) { return provider(name, { $get: factoryFn }); } function service(name, constructor) { return factory(name, ['$injector', function($injector) { return $injector.instantiate(constructor); }]); } function value(name, val) { return factory(name, valueFn(val)); } function constant(name, value) { assertNotHasOwnProperty(name, 'constant'); providerCache[name] = value; instanceCache[name] = value; } Source:
  36. 36. Directives Isolate Scope: Directive-specific scope – Assists in creating reusable components – Prevents or other components from changing your model state app .controller("myController", function($scope){ $scope.doSomething = function(something){...}; }) .directive('myDirective', function () { return { restrict: "E", scope:{ done:"&" }, template:'my-template.html' } }); The 'scope' option isolates the directive's scope.
  37. 37. Directives Directive Definition Options: Instructions to the ng compiler app .controller("myController", function($scope){ $scope.doSomething = function(something){...}; }) .directive('myDirective', function () { return { restrict: "E", priority:sort order before compilation, terminal: if true, process this directive last, scope: true, false, or {} (isolate) controller: instantiate before pre-linking phase..., require:..another directive and inject its controller... controllerAs:controller alias at the directive scope... type: doctype ('html','svg','math'), template:replace current element with.... templateUrl: same as above, but async from url... replace: where to insert template..., transclude: precompile element....., compile: transform template Dom..., link: update Dom, register listeners..., } restrict: matching restriction options: 'A' - only matches attribute name 'E' - only matches element name 'C' - only matches class name 'M' - only matches comment or any combination. (eg: 'AE') default: 'A'
  38. 38. Directives Directive Definition Options: Instructions to the compiler app .controller("myController", function($scope){ $scope.doSomething = function(something){...}; }) .directive('myDirective', function () { return { restrict: "E", priority:sort order before compilation, terminal: if true, process this directive last, scope: true, false, or {} (isolate) controller: instantiate before pre-linking phase..., require:..another directive and inject its controller... controllerAs:controller alias at the directive scope... type: doctype ('html','svg','math'), template:replace current element with.... templateUrl: same as above, but async from url... replace: where to insert template..., transclude: precompile element....., compile: transform template Dom..., link: update Dom, register listeners..., } Deferring to api: https://docs.angularjs.org/api/ng/service/ $compile#description_comprehensive-directive- api_directive-definition-object
  39. 39. Unit Testing ● Test on real devices ● Remote control ● Testing framework agnostic (Jasmine, Mocha, QUnit... or write adapter) ● Simple CI integration (Jenkins, Travis, Semaphore) ● Open Source ● Easy to debug from IDE Karma
  40. 40. End-to-End (e2e) Testing Protractor ● Thin wrapper for webdriver.js ● Support for cross-browser testing using Selenium Webdriver ● Support for GhostDriver/PhantomJs (Wip) ● Includes webdriver-manager for drivers, Selenium installation, and updates to both ● Includes elementExplorer for building locators ● Integrates with Saucelabs, easy enough to port over to BrowserStack
  41. 41. End-to-End (e2e) Testing ● Protractor – Recommends the Page Object Model design pattern for testing
  42. 42. End-to-End (e2e) Testing ● Protractor var flow = browser.driver.controlFlow(); // pseudocode login = function(username){...} navigateToReviews = function(){...} addNewReview = function(){...} flow.execute(login('Walt')); flow.execute(navigateToReviews); flow.execute(addNewReview); (Optional) Tap into webdriver.js:
  43. 43. Continuous Integration ● Jenkins + NodeJs plugin ● Unit tests run via Grunt and Karma ● e2e tests are still a work-in-progress: – Rely on npm concurrent, connect(express), scripts for setup + watch and teardown – Awaiting reintroduction of timing in Jasmine for PhantomJs tests – Awaiting Saucelabs/BrowserStack credentials for cross-browser tests
  44. 44. Real World Experiences: Project Challenges Project challenges are similar to those of all large projects: ● Discovering and establishing best practices amongst contributors ● Directory structures/file taxonomy, refactoring with project growth ● Keeping libraries up do date, Bower in the loop ● Rediscovery of conveniences found in mature frameworks ● Multiple solutions, evaluation, and selection
  45. 45. Real World Experiences: New Challenges ● Adjustments for all Ramp up on new framework and concepts Continuous delivery and deployment challenges (binary artifacts, externalizing conf) Various tools/tools in motion (grunt, node/npm, bower, css compilers, yeoman) ● Front-end veterans New conventions, structures, design patterns (not just jquery, js, css any more) More responsibility for application architecture ● Back-end veterans Javascript as the primary language (callbacks, promises, debugging, refactoring..) UX, responsive Coordination with rest apis and content delivery service
  46. 46. Real World Experiences:Gotchas ● Potential for memory leaks/weird behavior with scope misuse ● Bower gone wild ● Dependency additions, revisions (npm need-to-know) ● Library/dependency bloat ● Issues/feature requests in (ng and integrated) libraries and tools
  47. 47. Tool Support: IDEs & Refactoring ● IntelliJ Idea, WebStorm ● Vim, SublimeText ● Netbeans ● Visual Studio Behold the Plug-Ins!
  48. 48. Tool Support: Misc. Open Source Frameworks ● Yeoman (Yo, Grunt, Bower) + generators http://yeoman.io/ ● Lots of Grunt plugins ● Lots of Npm packages ● Batarang plugin for Chrome ● Browser web developer console
  49. 49. Tool Support: Static Code Analysis ● JsHint: http://www.jshint.com/ ● grunt-contrib-jshint: https://github.com/gruntjs/grunt-contrib-jshint ● Enforces code quality using rules ● Configured tasks in grunt pass directly to jshint ● Customizable – reporter output, – options and globals – ignores for specific warnings ● grunt-contrib-concat: Linting before and after concatenating files
  50. 50. Tool Support: Code Coverage ● Karma + Istanbul: karma-coverage https://github.com/karma-runner/karma-coverage ● Generates reports in several formats including Cobertura xml (integration with Jenkins) ● Protractor (none, lots of unit tests, REST apis covered on their end)
  51. 51. Resources for Learning ● stackoverflow ● angularjs.org ● AngularJs api docs: https://docs.angularjs.org/api ● github (docs, plunkers, demos) ● egghead.io (free and subscription) ● AngularJs Style Guide: https://google-styleguide.googlecode.com/svn/trunk/angularjs-google-style.html ● angular-phonecat tutorial: http://docs.angularjs.org/tutorial ● Los Techies AngularJs: http://lostechies.com/gabrielschenker/2014/02/26/angular-js-blog-series-table-of-content/
  52. 52. Q&A
  53. 53. Demo examples: https://github.com/kthblmfld/angularjs-from-scripts
  1. A particular slide catching your eye?

    Clipping is a handy way to collect important slides you want to go back to later.

×