Table of Contents
- Preface
- Chapter 1: Angular Zen
- Meet AngularJS
- Getting familiar with the framework
- Finding your way in the project
- The community
- Online learning resources
- Libraries and extensions
- Tools
- Batarang
- Plunker and jsFiddle
- IDE extensions and plugins
- AngularJS crash course
- Hello World – the AngularJS example
- Two-way data binding
- The MVC pattern in AngularJS
- Bird's eye view
- Scopes in depth
- View
- Modules and dependency injection
- Modules in AngularJS
- Collaborating objects
- Registering services
- Modules lifecycle
- Modules depending on other modules
- Hello World – the AngularJS example
- AngularJS and the rest of the world
- jQuery and AngularJS
- Apples and oranges
- A sneak peek into the future
- jQuery and AngularJS
- Summary
- Meet AngularJS
- Chapter 2: Building and Testing [ ii ]
- Introducing the sample application
- Getting familiar with the problem domain
- Technical stack
- Persistence store
- MongoLab
- Server-side environment
- Third-party JavaScript libraries
- Bootstrap CSS
- Build system
- Build system principles
- Automate everything
- Fail fast, fail clean
- Different workflows, different commands
- Build scripts are code too
- Tools
- Grunt.js
- Testing libraries and tools
- Jasmine
- Karma runner
- Build system principles
- Organizing files and folders
- Root folders
- Inside the source folder
- AngularJS specific files
- Start simple
- Inside the test folder
- File-naming conventions
- AngularJS modules and files
- One file, one module
- Inside a module
- Different syntax for registering providers
- Syntax for declaring the configure and run blocks
- Automated testing
- Unit tests
- Anatomy of a Jasmine test
- Testing AngularJS objects
- Testing services
- Testing controllers
- Mock objects and asynchronous code testing
- End-to-end tests
- Daily workflow
- Karma runner tips and tricks
- Executing a subset of tests
- Debugging
- Unit tests
- Summary
- Introducing the sample application
- Chapter 3: Communicating with a Back-end Server [ iii ]
- Making XHR and JSONP requests with $http
- Getting familiar with the data model and MongoLab URLs
- $http APIs quick tour
- The configuration object primer
- Request data conversion
- Dealing with HTTP responses
- Response data conversion
- Dealing with same-origin policy restrictions
- Overcoming same-origin policy restrictions with JSONP
- JSONP limitations
- Overcoming same-origin policy restrictions with CORS
- Server-side proxies
- The promise API with $q
- Working with promises and the $q service
- Learning $q service basics
- Promises are first-class JavaScript objects
- Aggregating callbacks
- Registering callbacks and the promise lifecycle
- Asynchronous action chaining
- More on $q
- $q integration in AngularJS
- Working with promises and the $q service
- The promise API with $http
- Communicating with RESTful endpoints
- The $resource service
- Constructor-level and instance-level methods
- $resource creates asynchronous methods
- Limitations of the $resource service
- Custom REST adapters with $http
- The $resource service
- Using advanced features of $http
- Intercepting responses
- Testing code that interacts with $http
- Summary
- Making XHR and JSONP requests with $http
- Chapter 4: Displaying and Formatting Data
- Referencing directives
- Displaying results of expression evaluation
- The interpolation directive
- Rendering model values with ngBind
- HTML content in AngularJS expressions
- Conditional display
- Including blocks of content conditionally
- Rendering collections with the ngRepeat directive
- Getting familiar with the ngRepeat directive
- Special variables [ iv ]
- Iterating over an object's properties
- ngRepeat patterns
- Lists and details
- Altering tables, rows, and classes
- DOM event handlers
- Working effectively with DOM-based templates
- Living with verbose syntax
- ngRepeat and multiple DOM elements
- Elements and attributes that can't be modified at runtime
- Custom HTML elements and older versions of IE
- Handling model transformations with filters
- Working with built-in filters
- Formatting filters
- Array-transforming filters
- Writing custom filters – a pagination example
- Accessing filters from the JavaScript code
- Filters dos and don'ts
- Filters and DOM manipulation
- Costly data transformations in filters
- Unstable filters
- Working with built-in filters
- Summary
- Chapter 5: Creating Advanced Forms
- Comparing traditional forms with AngularJS forms
- Introducing the ngModel directive
- Creating a User Information Form
- Understanding the input directives
- Adding the required validation
- Using text-based inputs (text, textarea, e-mail, URL, number)
- Using checkbox inputs
- Using radio inputs
- Using select inputs
- Providing simple string options
- Providing dynamic options with the ngOptions directive
- Using empty options with the select directive
- Understanding select and object equivalence
- Selecting multiple options
- Working with traditional HTML hidden input fields
- Embedding values from the server
- Submitting a traditional HTML form
- Looking inside ngModel data binding
- Understanding ngModelController
- Transforming the value between the model and the view
- Tracking whether the value has changed [ v ]
- Tracking input field validity
- Understanding ngModelController
- Validating AngularJS forms
- Understanding ngFormController
- Using the name attribute to attach forms to the scope
- Adding dynamic behavior to the User Information Form
- Showing validation errors
- Disabling the save button
- Disabling native browser validation
- Understanding ngFormController
- Nesting forms in other forms
- Using subforms as reusable components
- Repeating subforms
- Validating repeated inputs
- Handling traditional HTML form submission
- Submitting forms directly to the server
- Handling form submission events
- Using ngSubmit to handle form submission
- Using ngClick to handle form submission
- Resetting the User Info form
- Summary
- Comparing traditional forms with AngularJS forms
- Chapter 6: Organizing Navigation
- URLs in single-page web applications
- Hashbang URLs in the pre-HTML5 era
- HTML5 and the history API
- Using the $location service
- Understanding the $location service API and URLs
- Hashes, navigation within a page, and $anchorScroll
- Configuring the HTML5 mode for URLs
- Client side
- Server side
- Handcrafting navigation using the $location service
- Structuring pages around routes
- Mapping routes to URLs
- Defining controllers in route partials
- The missing bits in the handcrafted navigation
- Using built-in AngularJS routing services
- Basic routes definition
- Displaying the matched route's content
- Matching flexible routes
- Defining default routes
- Accessing route parameter values
- Reusing partials with different controllers
- Avoiding UI flickering on route changes
- Preventing route changes [ vi ]
- Basic routes definition
- Limitations of the $route service
- One route corresponds to one rectangle on the screen
- Handling multiple UI rectangles with ng-include
- No nested routes support
- One route corresponds to one rectangle on the screen
- Routing-specific patterns, tips, and tricks
- Handling links
- Creating clickable links
- Working with HTML5 and hashbang mode links consistently
- Linking to external pages
- Organizing route definitions
- Spreading route definitions among several modules
- Fighting code duplication in route definitions
- Handling links
- Summary
- URLs in single-page web applications
- Chapter 7: Securing Your Application
- Providing server-side authentication and authorization
- Handling unauthorized access
- Providing a server-side authentication API
- Securing partial templates
- Stopping malicious attacks
- Preventing cookie snooping (man-in-the-middle attacks)
- Preventing cross-site scripting attacks
- Securing HTML content in AngularJS expressions
- Allowing unsafe HTML bindings
- Sanitizing HTML
- Preventing the JSON injection vulnerability
- Preventing cross-site request forgery
- Adding client-side security support
- Creating a security service
- Showing a login form
- Creating security-aware menus and toolbars
- Hiding the menu items
- Creating a login toolbar
- Supporting authentication and authorization on the client
- Handling authorization failures
- Intercepting responses
- HTTP response interceptors
- Creating a securityInterceptor service
- Creating the securityRetryQueue service
- Notifying the security service
- Preventing navigation to secure routes
- Using route resolve functions
- Creating the authorization service [ vii ]
- Summary
- Providing server-side authentication and authorization
- Chapter 8: Building Your Own Directives
- What are AngularJS directives?
- Understanding the built-in directives
- Using directives in the HTML markup
- Following the directive compilation life-cycle
- Writing unit tests for directives
- Defining a directive
- Styling buttons with directives
- Writing a button directive
- Understanding AngularJS widget directives
- Writing a pagination directive
- Writing tests for the pagination directive
- Using an HTML template in a directive
- Isolating our directive from its parent scope
- Interpolating the attribute with @
- Binding data to the attribute with =
- Providing a callback expression in the attribute with &
- Implementing the widget
- Adding a selectPage callback to the directive
- Creating a custom validation directive
- Requiring a directive controller
- Making the controller optional
- Searching for parents for the controller
- Working with ngModelController
- Writing custom validation directive tests
- Implementing a custom validation directive
- Requiring a directive controller
- Creating an asynchronous model validator
- Mocking up the Users service
- Writing tests for asynchronous validation
- Implementing the asynchronous validation directive
- Wrapping the jQueryUI datepicker directive
- Writing tests for directives that wrap libraries
- Implementing the jQuery datepicker directive
- Summary
- What are AngularJS directives?
- Chapter 9: Building Advanced Directives
- Using transclusion
- Using transclusion in directives
- Transcluding into an isolated scope directive
- Creating an alert directive that uses transclusion [ viii ]
- Understanding the replace property in the directive definition
- Understanding the transclude property in the directive definition
- Inserting the transcluded elements with ng-transclude
- Understanding the scope of transclusion
- Creating and working with transclusion functions
- Creating a transclusion function with the $compile service
- Cloning the original elements when transcluding
- Accessing transclusion functions in directives
- Getting the transclusion function in the compile function with transcludeFn
- Getting the transclusion function in the directive controller with $transclude
- Creating an if directive that uses transclusion
- Using the priority property in a directive
- Creating a transclusion function with the $compile service
- Understanding directive controllers
- Injecting special dependencies into directive controllers
- Creating a controller-based pagination directive
- controllers and link functions Understanding the difference between directive
- Injecting dependencies
- The compilation process
- Accessing other controllers
- Accessing the transclusion function
- Creating an accordion directive suite
- Using a directive controller in accordion
- Implementing the accordion directive
- Implementing the accordion-group directive
- Taking control of the compilation process
- Creating a field directive
- Using the terminal property in directives
- Using the $interpolate service
- Binding to validation messages
- Loading templates dynamically
- Setting up the field template
- Creating a field directive
- Summary
- Using transclusion
- for an International Audience Chapter 10: Building AngularJS Web Applications
- Using locale-specific symbols and settings
- Configuring locale-specific modules
- Making use of available locale settings
- Locale-specific settings and AngularJS filters
- Handling translations
- Handling translated strings used in AngularJS templates
- Using filters
- Using directives
- Handling translated strings used in the JavaScript code [ ix ]
- Handling translated strings used in AngularJS templates
- Patterns, tips, and tricks
- Initializing applications for a given locale
- Consequences of including locales as part of URLs
- Switching locales
- Custom formatting for dates, numbers, and currencies
- Initializing applications for a given locale
- Summary
- Using locale-specific symbols and settings
- Chapter 11: Writing Robust AngularJS Web Applications
- Understanding the inner workings of AngularJS
- It is not a string-based template engine
- Updating models in response to DOM events
- Propagating model changes to the DOM
- Synchronizing DOM and model
- Scope.$apply – a key to the AngularJS world
- Putting it all together
- It is not a string-based template engine
- Performance tuning – set expectations, measure, tune, and repeat
- Performance tuning of AngularJS applications
- Optimizing CPU utilization
- Speeding up $digest loops
- Entering the $digest loop less frequently
- Limit the number of turns per $digest loop
- Optimizing memory consumption
- Avoid deep-watching whenever possible
- Consider the size of expressions being watched
- The ng-repeat directive
- Collection watching in ng-repeat
- Many bindings made easy
- Optimizing CPU utilization
- Summary
- Understanding the inner workings of AngularJS
- Web Applications Chapter 12: Packaging and Deploying AngularJS
- Improving network-related performance
- Minifying static resources
- How does AngularJS infer dependencies?
- Writing minification-safe JavaScript code
- The pitfalls of array-style DI annotations
- Preloading templates
- Using the
- Minifying static resources
- Improving network-related performance