for commercial real estate teams Web/mobile workflow and collaboration tool Single page app => lots of in-page interactivity Rich data model => lots of data binding. Getting started: ! ! ! Today: 58 controllers / 107 factories (mostly models) / 65 directives 71K LOC (CoffeeScript/JavaScript) including specs 2
candidates in the past 4 weeks 17 open issues filed against RC4 Getting closer, but the final release is still TBD Lots of enhancements, it’s worth getting ahead of the curve…here’s our top ten. 3
fixed set of rules: Changes to the input are written immediately to the model (e.g., in the change event handler) Invalid view values are translated to undefined Supports simple object properties (no getter/setter) Angular 1.3 allows configuration via ngModelOptions 5
be updated. Useful to defer validation until focus leaves control (“blur”) debounce (Number – ms) Debounce view events. Useful for inputs that filter result sets or on pages with slow digest cycles. timezone (String) Specify timezone to use when reading/writing a Date instance. allowInvalid (Boolean) Write “invalid” data to model. Useful when doing server side validation, saving partial data, or persisted models no longer match new validations. getterSetter (Boolean) Functions bound to ngModel will be used as the model getter/setter. Useful to translate between view and internal representations. 6 1. Configurable Model Binding
down Angular digest cycles For example, large tables with lots of {{ cellValues }} To help mitigate this problem, Angular 1.3 natively supports “one time binding” Once an expression evaluates to a non-undefined value, its watcher is automatically deregistered Prefix the expression with :: <span>Welcome, {{ ::user.name }}.</span> <div ng-‐repeat=“user in ::users | filter:{active: true}”> Built into $parse (i.e., no special $watch syntax required in custom directives) 7
of parse/format functions ($parsers and $formatters). Conflates view parsing, model formatting and validation Overly complex for simple validations. Angular 1.3 introduces a simpler API called the validators pipeline. Implement a function that takes a model value and returns true if it’s valid. Add your custom validator as a property of ctrl.$validators 3. Validators Pipeline 8
API to check if a user ID is valid Async validators return a promise that will be resolved / rejected depending on the model validity. Add your custom validator as a property of ctrl. $asyncValidators Only called when all the other validators “pass” Avoid hitting APIs with data that’s known to be invalid 4. Asynchronous Validators 9
the control has seen a blur event. e.g., defer validation errors until the user tabbed through the control. ngModelCtrl.$pending True if an asynchronous validation is pending. e.g., display a “Checking user name…” type indicator. ngFormCtrl.$submitted Tracks whether the form has seen a submit event. e.g., defer validation errors until the user attempts to submit the form. 10
to present validation error messages: <li ng-‐if=“$error.required”>… <li ng-‐if=“$error.pattern and !$error.required”>… Angular 1.3 introduces ngMessages / ngMessage Declaratively specify error messages for a given control By default shows first error (or set ng-‐messages-‐multiple) Include global error message strings with ng-‐messages-‐include 11
function dependencies: 1. Implicitly via parameter names 2. Explicitly using inline array notation 3. Explicitly using $inject property annotation JavaScript minification breaks implicit dependencies: Error: [$injector:unpr] Unknown provider: aProvider <-‐ a Strict DI mode only supports explicit annotations, which means missing annotations are found before code ships to production (yay!) <div ng-‐app=“myApp” ng-‐strict-‐di> 12
(i.e., perform one $digest) $rootScope.$watchGroup Convenience function to watch an array of expressions $templateRequest Helper function to download and cache templates $compileProvider.debugInfoEnabled Disable element attributes (e.g., ng-‐scope) and data (e.g., $scope) used for debugging (7% performance bump on large table benchmark) 13
scope variable “user in users | filter:keyword as matchingUsers”> Filter predicate functions are passed the element index function evenElementsPred(e, i) { return i % 2 == 0; } limitTo supports numbers (limits number of digits displayed) {{ 12345 | limitTo:2 }} => “12” date has timezone support (UTC or browser) {{ 0 | date:'HH':'UTC' }} => “00” 14
are assumed to be stateless (opt-out with $stateful) attr.$observe returns a deregistration function (not the observer) <base> is required if $location HTML5 mode is enabled Input type=“password” values are not trimmed by default Dropping support for jQuery < 2.1.1 and IE8 (`—screw-ie8`) But wait, there’s more! See the CHANGELOG for the full list. 16