Thursday, May 22, 2014

What are the Basic Building Blocks of AngularJS?


HTML with additional markup
extend HTML with custom attributes and elements. Dirrectives tell HTML compiler to attach specific behaviour to a DOM emement.
the data shown to the user in the view and with which the user interacts
context where the model is stored so that controllers, directives and expressions can access it
access variables and functions from the scope
parses the template and instantiates directives and expressions
formats the value of an expression for display to the user
what the user sees (the DOM)
sync data between the model and the view
the business logic behind views
Creates and wires objects and functions
dependency injection container
a container for the different parts of an app including controllers, services, filters, directives which configures the Injector
reusable business logic independent of views

Wednesday, May 21, 2014

Angular Language Rules

Angular Language Rules:
  • Manage dependencies with Closure's goog.require and goog.provide
  • Modules
  • Modules should reference other modules using the "name" property
  • Use the provided Angular externs file
  • JSCompiler Flags
  • Controllers and Scopes
  • Directives
  • Services

1. Manage dependencies with Closure's goog.require and goog.provide

Choose a namespace for your project, and use goog.provide and goog.require.
goog.provide('hello.about.AboutCtrl');
goog.provide('hello.versions.Versions');
Why? Google BUILD rules integrate nicely with closure provide/require.

http://code.google.com/p/closure-compiler/wiki/ManageClosureDependencies
Detail About Closure https://github.com/google/closure-compiler
How to implement: http://apphacker.wordpress.com/2009/12/28/howto-how-to-use-goog-require-and-goog-provide-for-your-own-code/

2.Modules should reference other modules using the Angular Module's "name" property
For example:
// file submodulea.js:
  goog.provide('my.submoduleA');

  my.submoduleA = angular.module('my.submoduleA', []);
  // ...

// file app.js
  goog.require('my.submoduleA');

  Yes: my.application.module = angular.module('hello', [my.submoduleA.name]);
  
      No: my.application.module = angular.module('hello', ['my.submoduleA']);
  
Why? Using a property of my.submoduleA prevents Closure presubmit failures complaining that the file is required but never used. Using the .name property avoids duplicating strings.

Use a common externs file

This maximally allows the JS compiler to enforce type safety in the presence of externally provided types from Angular, and means you don't have to worry about Angular vars being obfuscated in a confusing way.
Note to readers outside Google: the current externs file is located in an internal-to-Google directory, but an example can be found on github here.

JSCompiler Flags

Reminder: According to the JS style guide, customer facing code must be compiled.
Recommended: Use the JSCompiler (the closure compiler that works with js_binary by default) and ANGULAR_COMPILER_FLAGS_FULL from //javascript/angular/build_defs/build_defs for your base flags.
Note - if you are using @export for methods, you will need to add the compiler flag
"--generate_exports",
If you are using @export for properties, you will need to add the flags:
"--generate_exports",
"--remove_unused_prototype_props_in_externs=false",
"--export_local_property_definitions",

Controllers and Scopes

Controllers are classes. Methods should be defined on MyCtrl.prototype. See the JavaScript style guide
Google Angular applications should use the 'controller as' style to export the controller onto the scope. This is fully implemented in Angular 1.2 and can be mimicked in pre-Angular 1.2 builds.
Pre Angular 1.2, this looks like:
/**
 * Home controller.
 *
 * @param {!angular.Scope} $scope
 * @constructor
 * @ngInject
 * @export
 */
hello.mainpage.HomeCtrl = function($scope) {
  /** @export */
  $scope.homeCtrl = this; // This is a bridge until Angular 1.2 controller-as

  /**
   * @type {string}
   * @export
   */
  this.myColor = 'blue';
};


/**
 * @param {number} a
 * @param {number} b
 * @export
 */
hello.mainpage.HomeCtrl.prototype.add = function(a, b) {
  return a + b;
};
And the template:
<div ng-controller="hello.mainpage.HomeCtrl"/>
  <span ng-class="homeCtrl.myColor">I'm in a color!</span>
  <span>{{
homeCtrl.add(5, 6)}}</span> </div>
After Angular 1.2, this looks like:
/**
 * Home controller.
 *
 * @constructor
 * @ngInject
 * @export
 */
hello.mainpage.HomeCtrl = function() {
  /**
   * @type {string}
   * @export
   */
  this.myColor = 'blue';
};


/**
 * @param {number} a
 * @param {number} b
 * @export
 */
hello.mainpage.HomeCtrl.prototype.add = function(a, b) {
  return a + b;
};
If you are compiling with property renaming, expose properties and methods using the @export annotation. Remember to @export the constructor as well.
And in the template:
<div ng-controller="hello.mainpage.HomeCtrl as homeCtrl"/>
  <span ng-class="homeCtrl.myColor">I'm in a color!</span>
  <span>{{homeCtrl.add(5, 6)}}</span>
</div>
Why? Putting methods and properties directly onto the controller, instead of building up a scope object, fits better with the Google Closure class style. Additionally, using 'controller as' makes it obvious which controller you are accessing when multiple controllers apply to an element. Since there is always a '.' in the bindings, you don't have to worry about prototypal inheritance masking primitives.

Directives

All DOM manipulation should be done inside directives. Directives should be kept small and use composition. Files defining directives should goog.provide a static function which returns the directive definition object.
goog.provide('hello.pane.paneDirective');

/**
 * Description and usage
 * @return {angular.Directive} Directive definition object.
 */
hello.pane.paneDirective = function() {
  // ...
};
Exception: DOM manipulation may occur in services for DOM elements disconnected from the rest of the view, e.g. dialogs or keyboard shortcuts.

Services

Services registered on the module with module.service are classes. Use module.service instead of module.provider or module.factory unless you need to do initialization beyond just creating a new instance of the class.
/**
 * @param {!angular.$http} $http The Angular http service.
 * @constructor
 */
hello.request.Request = function($http) {
  /** @type {!angular.$http} */
  this.http_ = $http;
};

hello.request.Request.prototype.get = function() {/*...*/};
In the module:
module.service('request', hello.request.Request

What is new in angularjs 1.3 ?

AngularJS 1.3: a new release approaches
Heads up! A new Angular release is on its way. Since we plan to discontinues support for old browsers, we wanted to give you plenty of notice. As a secondary goal, this release will cover features to improve performance, and small API fixes that require small breaking changes and removal of apis that were previously deprecated. We're also making a change to how we number stable/unstable releases.

AngularJS 1.3 discontinues support for Internet Explorer 8


Why we're doing this:

  • Modern browsers have evolved. Although our stats tell us that only a small percentage of users are on Internet Explorer 8, maintaining compatibility requires code that slows the rest of AngularJS down.
  • In April 2014, Microsoft will be ending support for Windows XP, which means the end of support for the operating system most of Internet Explorer 8 users use.


Dropping support for Internet Explorer 8  will enable us to add more exciting features to Angular faster, decrease Angular's support burden, and cut our build time in half, while affecting only a very small proportion of users.


But what if your users still rely heavily on Internet Explorer 8? If your app needs to keep supporting older browsers, you have a few options:


  • Keep using Angular 1.2.x.
  • Use 1.3 and test (or if you're feeling lucky, hope for the best). The changes in version 1.3 won't be actively removing the hacks in Angular that make Internet Explorer 8 work. Most things that work now will probably keep working. But we're going to stop testing against Internet Explorer 8 in our CI server configuration. And we won't be fixing issues that are solely related to support for Internet Explorer 8 users.
  • Look for commercial support outside the core project - the Angular ecosystem is now big enough that it wouldn't be shocking to us if a company started offering commercial support for Angular apps on IE8. (entrepreneurs: hint hint!)


Removal of deprecated apis



We are aiming at the promise unwrapping in Angular templates that we deprecated before v1.2.


New naming conventions for release versions



Since our long term goal is to move to semantic versioning (semver) for Angular 2.0, starting with AngularJS 1.3 we are replacing odd/even versioning we used previously with semver's pre-release notation.


What does that mean?

  • The first stable release under the 1.3.x release train will be 1.3.0.
  • Unstable releases toward 1.3.0 will use semver's pre-release notation (#.#.#-text.#) So, for example, 1.3.0-beta.1 and 1.3.0-beta.2 would be unstable releases.

What is the goal of Angularjs 2.0?

 AngularJS 2.0
As we’re starting into the implementation of AngularJS 2.0, we thought we should put pen to paper and give you some insight into how we’re thinking about the design and why we’re making the changes we are.  We’re sharing it with you now so you can help make the right choices.


AngularJS 2 is a framework for mobile apps.  It is for desktop as well, but mobile is the hard bit that we will get right first.  The AngularJS you know and, hopefully, love will still be there with data-binding, extensible HTML, and a focus on testability. 


All the design docs for AngularJS 2 are publicly available on Google Drive.  This document contains a summary of our approach and design principles with links to specific designs in context.


CAVEAT: We’re still in design and prototyping stage for AngularJS 2.  Some of this will happen differently or not at all in the final product. 

Designed for the future

We’re designing AngularJS 2 for the way the world will look when we believe folks will use it.  In particular, this means targeting modern browsers and using ECMAScript 6.

Modern Browsers

Modern browsers means the set of browsers known as ‘evergreen’ or always automatically updated to the latest version.  Building for these browsers let us drop many hacks and workarounds that make AngularJS harder to use and develop on than it needs to be.

The set currently includes Chrome, FireFox, Opera, Safari, and IE10/11.  On mobile, we’ll support something close to the list of Chrome on Android, iOS 6+, Windows Phone 8+ and Firefox mobile.  We’re looking into supporting older versions of Android, but the jury is still out.


Yes, there are still older browsers in use, but we’re targeting these newer models as they will be the primary ones in use by the time AngularJS 2 is ready and you good developers have had time to build apps on it.

ECMAScript 6+ (design)

All code in AngularJS 2 is already being written in ES6.  As ES6 doesn’t run in browsers today, we’re using the Traceur compiler to generate the nice ES5 that runs everywhere.  We’re working with the Traceur team to build support for a few extensions like annotations and assertions


Don’t worry.  Though AngularJS will be in ES6, you can still write in ES5 if you don’t want to upgrade.  The compiler generates readable JS and there are human-sensible analogs for the extensions.  See the design doc for more info.

Faster

Faster change detection (design)

AngularJS apps are built around data-binding between DOM and JS objects.  The speed of AngularJS apps is driven largely by the underlying change detection mechanism we use.  We’ve talked at length on how we hoped to make this faster by using Object.observe() when it becomes available in Chrome M35.  And we will!


After some hard analysis (detailed in the doc), however, we’ve also found that we can make this much faster and more memory efficient even before this native change detection hits browsers.  Buttery-smooth app buttery-butterness is around the corner.

Instrumented (design)

The other half of the performance equation is the code that you write.  For this, we’ll provide high resolution timing details of where time gets spent in your application.  You can see in that this is a goal in the Change Detection design, but we’ll directly support this through a new Angular-wide logging service called diary.js.

Modular

When we released AngularJS 1.0, the features were in a take-it-or-leave-it single package.  You incur the download price for every piece whether you use it or not.  Though the whole of AngularJS is very small by desktop app standards, this can make a big difference on mobile devices.


One interesting thing we noticed was that when we split out the $route into a separate library, several innovative replacements popped up.  


For performance and to enable innovation, our goal is that almost every piece of AngularJS should be optional, replaceable, and even used in other non-AngularJS frameworks.  You’ll be able to pick and choose the parts you like and write or select others that you like better.

Other Performance topics

Though there are no designs yet, there are many other areas of performance optimization we’ll include in AngularJS.  From increasing first-load time with pre-parsed templates to ensuring silky smooth 60 frames per second animations, we’ll invest heavily on a fully optimized user experience.  Please help us by highlighting areas where we should focus and techniques you can contribute to the shipping solution. 

Simpler

Dependency Injection (design)

Dependency Injection is still a key differentiator between AngularJS and other client side frameworks in eliminating much of your application’s wiring code and making testability-by-default a reality.  Though we’ve enjoyed these benefits in building our applications, we’re dissatisfied with the current implementation.  We can make it less complex and more capable at the same time.


We’ll see a less complex DI by eliminating the config phase, simplifying the syntax by using declarative-style ES6+ annotations instead of imperative.  We’ll enjoy greater capabilities by integrating DI with module loading through ES6 Modules.  We’ll also see the ability to lazily-load parts of our JS through child injectors.


The doc linked above has our initial thoughts, but this is one part of AngularJS 2 that you can try today.  See the repo for current details on the implementation.

Templating and Directives (design)

The ability to specify templates directly in HTML and extend its syntax are the bread and butter of AngularJS.  We have some lofty goals for AngularJS’s template compiler in 2.  Namely:
  • Simplify the directive API
  • Integrate with other component frameworks using web standards
  • Improve performance
  • Allow tools like IDEs to analyze and validate templates


We’re so excited about these new bits that we can hardly wait to show them off.  There’s too much good stuff to extract into a summary, so please just go straight to the design doc to find out more.

More capable

Touch animations (design)

Users are accustomed to certain touch aware usage patterns. E.g. scroll through a list using their finger, circle through pictures in a carousel, remove list entries by swiping them away. However:
  • Current implementations of carousel, infinite scrolling, … don’t share a common core and by this have a lot of redundancy and different approaches.
  • Current implementations mostly don't provide an option to use native scroll events, as older browsers and also some current browsers don't support them well. However, by this they prevent the optimal performance on new devices.


We want to give these scenarios first-class support for the best user experiences possible in your applications.

Router (design)

The initial AngularJS router was designed to handle just a few simple cases. As AngularJS grew, we've slowly added more features. However, the underlying design is ill-suited to be extended much further.


We’re taking a careful look at known use cases and other router implementations across many application frameworks so we can deliver a simple yet extensible router that should fit the widest set of applications.


A few cases that we’re particularly keen on supporting include:
  • State-based routing
  • Integration with authentication and authorization
  • Optionally preserving state of some views.  Particularly needed for mobile!

Persistence (design)

Beyond AngularJS’s humble $http, many developers have desired a higher level abstraction for working with data from servers and local persistent data in the browser. 


Mobile apps need to work in an “always offline” mode with syn to the server.  RESTful services need more than we’ve provided in $resource.  Some data can be updated in batches while some needs a continuous streaming model. 


In this new persistence layer, we’ll provide clean structure for these cases and take much more out of the boilerplate currently necessary.

Q&A

When will it be done?

If you’ve been with us through the 1.2 announcement, you know that we don’t know. :)  Though we’re just posting the design docs now, we’re already prototyping many of the modules.  Dependency Injection and Zone.js appear to be usable.  All the work will be done on GitHub and we’ll continue to capture weekly meeting notes so you can follow along.

What will it be like to port an AngularJS 1.x application to AngularJS 2?

As AngularJS 2 is still in development, we honestly don’t know.  In our imagination, porting will be fairly straightforward but not free.  Taking advantage of ES6 will likely be the largest part of the job.   Templates will be largely the same with some mostly-mechanical find and replace exercises.  Your controllers contain your business logic and not much if any AngularJS API today.  Those should port easily.  The parts that will require the most thinking will be your use of Modules and Directives.

Is AngularJS 2 a replacement for mobile tech like PhoneGap or Ionic Framework?

No, AngularJS is still just the core framework.  You might still want libraries like Ionic for mobile-optimized CSS/JS components and tools like PhoneGap for app packaging and native API access.

How does AngularJS 2 relate to AngularDart?

When porting AngularJS to the Dart language, we build a new version of Angular using all the learnings we’d acquired to date.  Many of the improvements discussed in this document like improved Directive concepts and syntax and class/annotation-based DI are already present there. 


While the implementation isn’t what we’ll arrive at for 2, it’s a great preview of what’s to come. 

We’ll be upgrading AngularDart as we build AngularJS 2 so folks who prefer the Dart language can enjoy the same benefits as folks on JS.  Our goal is that there will be a single framework with your choice of language.


Other documents of interest