├── cool_stuff.md
├── LICENSE
├── testing-http-services.md
├── services.md
├── rxjs.md
├── README.md
├── router.md
├── angular2readiness.md
└── best-practices.md
/cool_stuff.md:
--------------------------------------------------------------------------------
1 | - [Virtual Scrolling](http://plnkr.co/edit/HVBw0bnGYwUt6P4j6uba?p=preview) - Rob Wormald
2 | - [Angular 2 + React](http://plnkr.co/edit/Sz9OKJaBtjQJb1F1kaIU) - Rob Wormald
3 | - [Polymer + Angular 2](http://plnkr.co/edit/yh0ACeu6g5n8D7YuhJvg?p=preview) - Rob Wormald
4 | - [Http Exponential Backoff](http://plnkr.co/edit/9kQju7I9jigf6PWsEpSf?p=preview) - Rob Wormald
5 | - [Date Picker Control](https://plnkr.co/edit/Xt4MlMp2sW35YLDX0u7M?p=preview) - Rob Wormald
6 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (c) 2015
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
23 |
--------------------------------------------------------------------------------
/testing-http-services.md:
--------------------------------------------------------------------------------
1 |
2 | [A solution from @jgongo](https://gitter.im/angular/angular?at=56a915aa80ad69394a7ad156) with some additional changes based on [comments from @krimple](https://gitter.im/angular/angular?at=56913628d739f50a36029ef7)
3 | ```typescript
4 | beforeEachProviders([
5 | HTTP_PROVIDERS,
6 | MockBackend,
7 | provide(XHRBackend, {useClass: MockBackend}),
8 | AuthenticationService
9 | ]);
10 |
11 |
12 | it('should return an error upon unsuccessful authentication', injectAsync([XHRBackend, AuthenticationService], (mockBackend, authenticationService) => {
13 | return new Promise((resolve, reject) => {
14 | mockBackend.connections.subscribe((connection: MockConnection) => {
15 | connection.readyState = ReadyState.Done;
16 | connection.response.error(new Response(new ResponseOptions({
17 | body: {error: 'invalid_grant', error_description: 'Incorrect username and / or password'},
18 | status: 400
19 | })));
20 | });
21 |
22 | authenticationService.authenticate({username: 'john.doe', password: '12345'}).subscribe(
23 | (oauthTokenResponse) => {
24 | reject(Error('Unexpected successful response'));
25 | },
26 | (error: Response) => {
27 | expect(error.status).toBe(400);
28 | expect(error.json().error).toBe('invalid_grant');
29 | expect(error.json().error_description).toBe('Incorrect username and / or password');
30 | }
31 | );
32 | });
33 | }));
34 | ```
35 |
--------------------------------------------------------------------------------
/services.md:
--------------------------------------------------------------------------------
1 | # Table of contents
2 | - [How do I create a service?](#how-do-i-create-a-service)
3 | - [How do I share a service instance between multiple components?](#how-do-i-share-a-service-instance-between-multiple-components)
4 | - [How do I communicate between two sibling components?](#how-do-i-communicate-between-two-sibling-components)
5 | - [How do I communicate between components using a shared service?](#how-do-i-communicate-between-components-using-a-shared-service)
6 |
7 | # How do I create a service?
8 | A service is just a TypeScript class. If your service has dependencies which need to be injected, you need to annotate it. The `Injectable()` annotation was created for this purpose.
9 | ```javascript
10 | export class LogService{}
11 |
12 | export class AuthService{}
13 | //This must be marked with an annotation so that Typescript will generate the information required to inject dependencies
14 | @Injectable()
15 | export class TodoService{
16 | constructor(private logService:LogService,private authService:AuthService){}
17 | }
18 | //Provides a single instance of LogService and TodoService to TodoComponent and all of its children
19 | @Component({
20 | providers:[LogService, TodoService]
21 | })
22 | export class TodoComponent{
23 | constructor(private service:TodoService){}
24 | }
25 | //Provide a single instance of AuthService to everything
26 | bootstrap(TodoComponent,[AuthService]);
27 | ```
28 | See also: [Injectable Metadata](https://angular.io/docs/ts/latest/api/core/InjectableMetadata-class.html)
29 |
30 | # How do I share a service instance between multiple components?
31 | Provide the service in a common parent or the bootstrap. Every time you provide a service you get a new instance.
32 |
33 | # How do I communicate between two sibling components?
34 | There are two common approaches; Use a shared service, or have a common parent pass messages between the two.
35 |
36 | # How do I communicate between components using a shared service?
37 |
38 | A shared service is one way of sharing data between components which are not directly related to each other (i.e. not the immediate parent or child).
39 |
40 | [Live example](http://plnkr.co/edit/cXhr8LwWrISJWpDRLDvL?p=preview)
41 |
42 | ```typescript
43 | import {bootstrap} from 'angular2/platform/browser';
44 | import {Component,Injectable} from 'angular2/core';
45 | import {Subject} from 'rxjs/Subject';
46 |
47 | /**
48 | * A shared service for displaying errors
49 | */
50 | export class ErrorService{
51 | latestError:Subject=new Subject();
52 | error(err:any){
53 | this.latestError.next(err);
54 | }
55 |
56 | }
57 |
58 | /*
59 | * Logs errors to the console.
60 | * A service which consumes the shared service and provides additional functionality.
61 | */
62 | @Injectable()
63 | export class ErrorConsoleService{
64 | constructor(private errorService:ErrorService){
65 | errorService.latestError.subscribe(err=>console.log(err));
66 | }
67 | }
68 |
69 | /*
70 | * Displays the latest error from the error service
71 | * A component which consumes the shared service
72 | */
73 | @Component({
74 | selector:'errors',
75 | template:`
{{service.latestError|async}}
`
76 | })
77 | export class ErrorComponent{
78 | constructor(private service:ErrorService){
79 |
80 | }
81 | }
82 |
83 | /*
84 | * A form component which when submitted pushes an error to the shared service
85 | */
86 | @Component({
87 | selector:'formcmp',
88 | template:`
89 | `
92 | })
93 | export class FormComponent{
94 | constructor(private service:ErrorService){}
95 | onSubmit() {
96 | this.service.error('form submitted');
97 | }
98 | }
99 |
100 | /**
101 | * Root app component
102 | */
103 | @Component({
104 | selector:'my-app',
105 | directives:[ErrorComponent,FormComponent],
106 | template:`
107 | `
108 | })
109 | export class App{
110 | //If ErrorConsoleService is not injected here, it will never be instantiated and won't work.
111 | constructor(private errConsole:ErrorConsoleService){}
112 |
113 | }
114 | bootstrap(App, [ErrorService,ErrorConsoleService])
115 | ```
116 | Additional documentation: http://coryrylan.com/blog/angular-2-observable-data-services
117 |
--------------------------------------------------------------------------------
/rxjs.md:
--------------------------------------------------------------------------------
1 | # Table of contents
2 | - [Adding operators (map is not defined)](#adding-operatorsobservables-map-is-not-defined)
3 | - [Full RxJS](#full-rxjs)
4 | - [Individual Operators](#individual-operators)
5 | - [Loading operators individually for RxJS + Angular2 + SystemJS](#loading-operators-individually-for-rxjs--angular2--systemjs)
6 | - [Configuration for full RxJS](#configuration-for-full-rxjs)
7 | - [Configuration for individual observables / operators](#configuration-for-individual-observables--operators)
8 | - [Simpler configuration](#simpler-configuration)
9 | - [Alternative configuration](#alternative-configuration)
10 | - [Reference](#reference)
11 | - [What are observables and where can I learn more about them and RxJS?](#what-are-observables-and-where-can-i-learn-more-about-them-and-rxjs)
12 | - [Redux + Rx + Angular2 / ngrx](#redux--rx--angular2--ngrx)
13 | - [Redux](#redux)
14 | - [ngrx](#ngrx)
15 |
16 | # Adding operators/observables (map is not defined)
17 |
18 | Due to the number of operators, the size of RxJS is very large. As such, they have provided a method to trim down the size when bundling where operators are added as needed.
19 | If you are using SystemJS, some further configuration is needed beyond what is discussed in this section. See:[Loading operators individually for RxJS + Angular2 + SystemJS](#loading-operators-individually-for-rxjs--angular2--systemjs)
20 |
21 | ## Full RxJS
22 | If you want to enable the full functionality of RxJS and don't care about bundle size, you can do:
23 | ```typescript
24 | import 'rxjs/Rx';
25 | import {Observable} from 'rxjs/Observable';
26 |
27 | Observable.of(1,2,3);
28 | ```
29 | or (from the RxJS docs)
30 | ```typescript
31 | import Rx from 'rxjs/Rx';
32 |
33 | Rx.Observable.of(1,2,3)
34 | ```
35 | ## Individual Operators
36 | If you wish to minimize your bundle size you can import individual operators and observables:
37 | ```typescript
38 | import {Observable} from 'rxjs/Observable';
39 | // No need to specify the operator, just import and it will autopatch
40 | import 'rxjs/add/operator/map';
41 | import 'rxjs/add/observable/from';
42 |
43 | Observable.fromArray([1,2,3]).map(val => val+1).subscribe((d) => console.log(d));
44 | ```
45 | It is suggested that operators and observables be added in your bootstrap or similar to avoid isses with operators not existing when you add them in a different class from where the Observable is created.
46 |
47 | Further Reading: https://github.com/ReactiveX/RxJS#installation-and-usage
48 |
49 | # Loading operators individually for RxJS + Angular2 + SystemJS
50 |
51 | This guide assumes you have the latest version of Angular2, RxJS 5 and SystemJS.
52 |
53 | In your index.html your System.config should look like this
54 |
55 | ## Configuration for full RxJS
56 |
57 | ```javascript
58 | System.config({
59 | map: {
60 | rxjs: 'node_modules/rxjs'
61 | },
62 | packages: {
63 | rxjs: { defaultExtension: 'js' }
64 | }
65 | }
66 | ```
67 | Note : this configuration is not needed if you're using the Rx.js bundle provided by angular2. See the [official plnkr](https://angular.io/resources/live-examples/tutorial/ts/plnkr.html).
68 |
69 | After you're done with this config, you can import them as in [Individual Operators](#individual-operators)
70 |
71 | ## Reference
72 |
73 | - Issue [RxJS #843](https://github.com/ReactiveX/RxJS/pull/843)
74 | - Issue [ng2 #5632](https://github.com/angular/angular/issues/5632)
75 | - Issue [ng2 #5749](https://github.com/angular/angular/issues/5749)
76 | - [plnkr with code example](http://plnkr.co/edit/jzd0SF70GBk1hrSsp4M8)
77 |
78 |
79 | # What are observables and where can I learn more about them and RxJS?
80 |
81 | - You may want to read this introduction: https://gist.github.com/staltz/868e7e9bc2a7b8c1f754
82 | - For visual examples of Rx see: [Rx Marbles](http://rxmarbles.com/)
83 | - [RxJS 4 operator documentation with examples](https://github.com/Reactive-Extensions/RxJS/tree/master/doc/api/core/operators) (applies reasonably to RxJS 5 in Angular 2)
84 | - @xgrommx put togther an awesome [rx book](http://xgrommx.github.io/rx-book/index.html)
85 | - [Filtering data using observables and form inputs](http://plnkr.co/edit/CTpE1DtaVzk1JU5eQWBu?p=preview)
86 | - [Drag and drop list (similar to JqueryUI sortable list)](http://plnkr.co/edit/LD5FJaI4OOFbKfvhjD4e?p=preview)
87 | - [Taking advantage of Observables in Angular 2](http://blog.thoughtram.io/angular/2016/01/06/taking-advantage-of-observables-in-angular2.html)
88 | - [Taking advantage of Observables in Angular 2 - Part 2](http://blog.thoughtram.io/angular/2016/01/07/taking-advantage-of-observables-in-angular2-pt2.html)
89 | - Youtube Talks
90 | - Rob Wormald
91 | - [Everything is a Stream](https://www.youtube.com/watch?v=UHI0AzD_WfY)
92 | - [Angular 2 Data Flow - Jeff Cross, Rob Wormald and Alex Rickabaugh](https://www.youtube.com/watch?v=bVI5gGTEQ_U)
93 | - [Angular 2 Data Flow - Rob Wormald](https://vimeo.com/144625829)
94 | - Non Free resources:
95 | - https://egghead.io/series/introduction-to-reactive-programming
96 | - https://pragprog.com/book/smreactjs/reactive-programming-with-rxjs
97 |
98 | # Redux + Rx + Angular2 / ngrx
99 |
100 | I suggest you look at [ngrx](https://github.com/ngrx) before going with redux proper, as it does the same sort of job. That is not to say that redux is bad or inappropriate, but if you're not already invested you may find it easier.
101 |
102 | ## Redux
103 | - [ng2+redux guide](http://www.syntaxsuccess.com/viewarticle/redux-in-angular-2.0) (Thanks @baloodevil)
104 | - It's out of scope for this faq, but a guide for Redux in general and why it is useful: [Egghead.io getting started with redux](https://egghead.io/series/getting-started-with-redux)
105 |
106 | ## ngrx
107 | - [store](https://github.com/ngrx/store)
108 | - [store example](https://github.com/ngrx/angular2-store-example)
109 | - [refactoring underway](https://github.com/fxck/angular2-store-example/tree/fxck-refactoring)
110 | - [examples](https://github.com/btroncone/ngrx-examples) (Thanks @btroncone)
111 | - [docs from @btroncone](https://github.com/btroncone/ngrx.github.io)
112 |
113 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Angular 2 Community FAQ
2 |
3 | # Table of Contents
4 |
5 | ## [General Angular 2 Questions](angular2readiness.md)
6 | - [When will Angular 2 be released?](angular2readiness.md#when-will-angular-2-be-released)
7 | - [Seriously though, can I get an estimate?](angular2readiness.md#seriously-though-can-i-get-an-estimate)
8 | - [Is it ready for me?](angular2readiness.md#is-it-ready-for-me)
9 | - [Beta](angular2readiness.md#beta)
10 | - [Stability/Bugginess](angular2readiness.md#stabilitybugginess)
11 | - [Known Regressions](angular2readiness.md#known-regressions)
12 | - [API Stability](angular2readiness.md#api-stability)
13 | - [Documentation](angular2readiness.md#documentation)
14 | - [Ecosystem](angular2readiness.md#ecosystem)
15 | - [Community/Blogs/Support/Etc...](angular2readiness.md#communityblogssupportetc)
16 | - [Do I have to use Typescript?](angular2readiness.md#do-i-have-to-use-typescript)
17 | - [Do I have to use a build system? What build system should I use?](angular2readiness.md#do-i-have-to-use-a-build-system-what-build-system-should-i-use)
18 | - [Router](angular2readiness.md#router)
19 | - [Internationalization](angular2readiness.md#internationalization)
20 | - [Animation](angular2readiness.md#animation)
21 | - [Twitter Bootstrap/Material Design](angular2readiness.md#twitter-bootstrapmaterial-design)
22 |
23 | ## Setting up Angular 2 with...
24 | - SystemJS
25 | - Webpack
26 | - JSPM
27 | - Rollup
28 | - ES5/ES6 (no ts)
29 | - Others (are there any others?)
30 |
31 | ## [RxJS](rxjs.md)
32 | - [Adding operators (map is not defined)](rxjs.md#adding-operatorsobservables-map-is-not-defined)
33 | - [Full RxJS](rxjs.md#full-rxjs)
34 | - [Individual Operators](rxjs.md#individual-operators)
35 | - [Loading operators individually for RxJS + Angular2 + SystemJS](rxjs.md#loading-operators-individually-for-rxjs--angular2--systemjs)
36 | - [Configuration for full RxJS](rxjs.md#configuration-for-full-rxjs)
37 | - [Configuration for individual observables / operators](rxjs.md#configuration-for-individual-observables--operators)
38 | - [Simpler configuration](rxjs.md#simpler-configuration)
39 | - [Alternative configuration](rxjs.md#alternative-configuration)
40 | - [Reference](rxjs.md#reference)
41 | - [What are observables and where can I learn more about them and RxJS?](rxjs.md#what-are-observables-and-where-can-i-learn-more-about-them-and-rxjs)
42 | - [Redux + Rx + Angular2 / ngrx](rxjs.md#redux--rx--angular2--ngrx)
43 | - [Redux](rxjs.md#redux)
44 | - [ngrx](rxjs.md#ngrx)
45 |
46 | ## [Router](router.md)
47 | - [How do I protect routes?](router.md#protecting-routes)
48 | - [How do I resolve data before a route activates?](router.md#resolving-route-data)
49 | - [How do I handle invalid URLs?](router.md#handling-invalid-urls)
50 | - [How do I add classes to elements that contain an active router link?](router.md#adding-classes-to-elements-containing-active-router-links)
51 | - [How do I add optional parameters for a route?](router.md#optional-parameters)
52 | - [How do I make a breadcrumb component?](router.md#breadcrumb-component)
53 | - [How do I make router components and directives available for every component?](router.md#global-router-directives)
54 | - [How do I use regular expressions for a route?](router.md#router-regex-serializer)
55 | - [How do I dynamically configure routes](router.md#router-dynamic-config)
56 |
57 | ## [Forms](#forms-1)
58 | - [Validation](#validation)
59 | - [Multiple Validators](#how-do-i-use-more-than-one-validator-on-a-single-control)
60 | - [Custom validation](#how-do-i-make-a-custom-validator)
61 | - [Async Validators](#how-do-i-make-an-async-validator)
62 | - [Dependent Validators](#how-do-i-validate-a-control-based-on-the-value-in-another-control)
63 | - [Complex Forms](#complex-forms)
64 | - [Dependent Inputs](#how-do-i-have-a-select-box-that-is-dependent-on-another-select-box)
65 | - [Form elements in sub components](#how-do-i-have-form-elements-in-sub-components)
66 |
67 | ## Templates
68 | - [How do I make n elements in an *ngFor without a model?](https://plnkr.co/edit/FTPFoylc8s8pEiVRMoB9?p=preview)
69 |
70 | ## [Services and Components](services.md)
71 | - [How do I create a service?](services.md#how-do-i-create-a-service)
72 | - [How do I share a service instance between multiple components?](services.md#how-do-i-share-a-service-instance-between-multiple-components)
73 | - [How do I communicate between two sibling components?](services.md#how-do-i-communicate-between-two-sibling-components)
74 | - [How do I communicate between components using a shared service?](services.md#how-do-i-communicate-between-components-using-a-shared-service)
75 |
76 | ## Testing
77 | - [How do I test an error path with Http and MockBackend?](testing-http-services.md)
78 |
79 | ## [Making fun things](cool_stuff.md)
80 | - Drag and Drop
81 | - Other fun things...
82 |
83 |
84 | # Router
85 |
86 | ## Any good tutorials for the Router?
87 | Not yet, in the meantime you can look at this: https://www.youtube.com/watch?v=z1NB-HG0ZH4
88 |
89 | You can also take a look at this Plunkr, which while complex, does just about everything you would want with the router. http://plnkr.co/edit/Bim8OGO7oddxBaa26WzR?p=preview
90 |
91 | ## [How do I do breadcrumbs with the Router?](http://plnkr.co/edit/4cw2fPv3vX36v5Lu9Dnq?p=preview)
92 |
93 | ## [How do I make the Router components and directives available for every component?](http://plnkr.co/edit/FmMBasgv1rC1Qs6sJTMA?p=preview)
94 |
95 | # Forms
96 |
97 | ## Validation
98 |
99 | ### [How do I use more than one validator on a single control?](https://plnkr.co/edit/5yO4HviXD7xIgMQQ8WKs?p=preview)
100 |
101 | ### [How do I make a custom validator?](https://plnkr.co/edit/5yO4HviXD7xIgMQQ8WKs?p=preview)
102 |
103 | ### [How do I make an async validator?](http://plnkr.co/edit/vlzDapiOgVWLNqltEbGb?p=preview)
104 |
105 | ### [How do I validate a control based on the value in another control?] (http://plnkr.co/edit/NqQhBPJJo1PzHfisvh9J?p=preview)
106 |
107 | ## Complex Forms
108 |
109 | ### [How do I have a select box that is dependent on another select box](http://plnkr.co/edit/VTCKxH82XVy6XswaiKbg?p=preview)
110 |
111 | AKA: How do I make a state/province dropdown that changes contents when the country changes?
112 |
113 | ### [How do I have form elements in sub components](https://plnkr.co/edit/awfs0HGLkJOd6qdY8rhF?p=preview)
114 |
--------------------------------------------------------------------------------
/router.md:
--------------------------------------------------------------------------------
1 | # Table Of Contents
2 | - [How do I protect routes?](#protecting-routes)
3 | - [How do I resolve data before a route activates?](#resolving-route-data)
4 | - [How do I handle invalid URLs?](#handling-invalid-urls)
5 | - [How do I add classes to elements that contain an active router link?](#adding-classes-to-elements-containing-active-router-links)
6 | - [How do I add optional parameters for a route?](#optional-parameters)
7 | - [How do I make a breadcrumb component?](#breadcrumb-component)
8 | - [How do I make router components and directives available for every component?](#global-router-directives)
9 | - [How do I use regular expressions for a route?](#router-regex-serializer)
10 | - [How do I dynamically configure routes](#router-dynamic-config)
11 |
12 | ## Protecting routes
13 |
14 | Routes are protected using the `CanActivate` decorator. Dependency Injection is not available within the CanActivate function without a workaround.
15 |
16 | http://plnkr.co/edit/SF8gsYN1SvmUbkosHjqQ?p=preview
17 |
18 | ## Resolving route data
19 |
20 | Resolving route data has not been implemented yet. As a workaround you can use the Dependency Injection workaround used with `CanActivate`, a custom router outlet, and a service to add providers for the route.
21 |
22 | http://plnkr.co/edit/SCNA0P?p=preview
23 |
24 | ## Optional parameters
25 |
26 | Any parameter that is not defined in your route `path` is considered optional and will be added to the URL as a query string parameter for top level routes or a matrix parameter for child routes.
27 |
28 | ```js
29 | @RouteConfig([
30 | { path: '/users/:id', component: Users, name: 'Users' }
31 | ])
32 | class AppComponent{}
33 | ```
34 |
35 | ```html
36 | John Smith
37 | ```
38 |
39 | ## Handling Invalid URLs
40 |
41 | This feature has not been implemented yet, but you can use a route with a wildcard parameter to redirect another route
42 |
43 | ```js
44 | @RouteConfig([
45 | { path: '/404', component: NotFound, name: 'NotFound' },
46 | { path: '/**', redirectTo: ['/NotFound'] }
47 | ])
48 | class AppComponent{}
49 | ```
50 |
51 | ## Adding classes to elements containing active router links
52 |
53 | This can be accomplished with a custom directive that finds the first `routerLink` and if it becomes active, it will add the class the element.
54 |
55 | ```js
56 | import {isPresent, isBlank} from 'angular2/src/facade/lang';
57 | import {Directive, Input, Query, QueryList, Renderer, ElementRef} from 'angular2/core';
58 | import {Router, RouterLink} from 'angular2/router';
59 |
60 | @Directive({ selector: '[routerActive]' })
61 | export class RouterActive {
62 | @Input('routerActive') activeClass;
63 |
64 | constructor(
65 | @Query(RouterLink) public routerLinks:QueryList,
66 | public element: ElementRef,
67 | public router: Router,
68 | public renderer: Renderer
69 | ) {}
70 |
71 | ngOnInit() {
72 | this.router.root.subscribe((_) => {
73 | this.checkActive();
74 | });
75 | }
76 |
77 | ngAfterViewInit() {
78 | if (!this.activeClass) {
79 | this.activeClass = 'router-link-active';
80 | }
81 |
82 | this.checkActive();
83 | }
84 |
85 | checkActive() {
86 | let active = this.routerLinks.first.isRouteActive;
87 | this.renderer.setElementClass(this.element.nativeElement, this.activeClass, active);
88 | }
89 | }
90 | ```
91 |
92 | ```js
93 | import {Component} from 'angular2/core';
94 | import {RouteConfig} from 'angular2/router';
95 | import {RouterActive} from './RouterActive';
96 |
97 | @Component({
98 | selector: 'my-app',
99 | template: `
100 |
110 | `,
111 | directives: [ROUTER_DIRECTIVES, RouterActive]
112 | })
113 | @RouteConfig([
114 | { path: '/', component: Home, name: 'Home' },
115 | { path: '/about', component: About, name: 'About' }
116 | ])
117 | export class AppComponent {}
118 | ```
119 |
120 | ## Breadcrumb component
121 |
122 | http://plnkr.co/edit/4cw2fPv3vX36v5Lu9Dnq?p=preview
123 |
124 | ## Global router directives
125 |
126 | Add the router components and directives to the platform directives. This will allow you to use the `routerLink` and `router-outlet` directives without adding ROUTER_DIRECTIVES to each component.
127 |
128 | ```js
129 | import {bootstrap} from 'angular2/platform/browser';
130 | import {App} from './app';
131 | import {provide, PLATFORM_DIRECTIVES} from 'angular2/core';
132 |
133 | bootstrap(App, [
134 | provide(PLATFORM_DIRECTIVES, {useValue: [ROUTER_DIRECTIVES], multi: true})
135 | ]);
136 | ```
137 |
138 | ## Router regex serializer
139 |
140 | To use regular expressions for route matching, you provide a regular expression and a serializer that will return the generated url.
141 |
142 | ```js
143 | @Component({
144 | selector: 'regex-route',
145 | template: `Regex Route`
146 | })
147 | class RegexRoute{}
148 |
149 | @RouteConfig([
150 | { name : 'RegexRoute',
151 | regex: '^/test/(.+)/(.+)$', // matches /test/:parama/:paramb
152 | serializer: (params) => new GeneratedUrl(`/${params.a}/${params.b}`, {}),
153 | component: RegexRoute
154 | }
155 | ])
156 | export class App {}
157 | ```
158 |
159 | ```html
160 | Regex Route
161 | ```
162 |
163 | ## Router dynamic config
164 |
165 | To generate a route config dynamically, inject the router into your main app component and configure the routes .
166 |
167 | ```js
168 | import {Router} from 'angular2/router';
169 |
170 | @Component({...})
171 | export class AppComponent {
172 | constructor(router: Router) {
173 | let routes = [];
174 |
175 | if (someCondition) {
176 | routes = [
177 | { path: '/', component: Home, name: 'Home' },
178 | { path: '/about', component: About, name: 'About' }
179 | ]);
180 | } else {
181 | routes = [
182 | { path: '/home', component: Home, name: 'Home', useAsDefault: true },
183 | { path: '/away', component: Away, name: 'Away' }
184 | ]);
185 | }
186 |
187 | router.config(routes);
188 | }
189 | }
190 | ```
191 |
--------------------------------------------------------------------------------
/angular2readiness.md:
--------------------------------------------------------------------------------
1 | # Table of Contents
2 |
3 | - [When will Angular 2 be released?](#when-will-angular-2-be-released)
4 | - [Seriously though, can I get an estimate?](#seriously-though-can-i-get-an-estimate)
5 | - [Is it ready for me?](#is-it-ready-for-me)
6 | - [Beta](#beta)
7 | - [Stability/Bugginess](#stabilitybugginess)
8 | - [Known Regressions](#known-regressions)
9 | - [API Stability](#api-stability)
10 | - [Documentation](#documentation)
11 | - [Ecosystem](#ecosystem)
12 | - [Community/Blogs/Support/Etc...](#communityblogssupportetc)
13 | - [Do I have to use Typescript?](#do-i-have-to-use-typescript)
14 | - [Do I have to use a build system? What build system should I use?](#do-i-have-to-use-a-build-system-what-build-system-should-i-use)
15 | - [Router](#router)
16 | - [Internationalization](#internationalization)
17 | - [Animation](#animation)
18 | - [Twitter Bootstrap/Material Design](#twitter-bootstrapmaterial-design)
19 |
20 | # When will Angular 2 be released?
21 |
22 | When it's ready.
23 |
24 | # Seriously though, can I get an estimate?
25 |
26 | Any estimate given will be wrong. A better question to ask might be 'is it ready for me?'
27 |
28 | # Is it ready for me?
29 |
30 | That depends. Some Google teams are already using Angular 2 in production. Let's break it down.
31 |
32 | # Beta
33 |
34 | The Angular 2 team has stated that what they have released is ready, and they hope to minimize any further breaking changes.
35 | Read the release announcement: http://angularjs.blogspot.ca/2015/12/angular-2-beta.html
36 |
37 | # Stability/Bugginess
38 |
39 | Angular 2 is very well tested~~, and does not exhibit a lot of bugs~~. Their git hub page shows compatibility for all the browsers they support, and they do benchmarks to test that they have not slowed things down. If you were to stick with a given release of Angular 2 in beta, you could go to production with it successfully. That said, there are some known regressions.
40 |
41 | ## Known Regressions
42 |
43 | Here are a number of known issues/regressions that the community has found affecting whether you could go to production with a given version of Angular 2
44 |
45 | - Since Beta 1
46 | - Attribute and class bindings throw an error when declared inside ngForm elements in Beta.1 [6374](https://github.com/angular/angular/issues/6374)
47 | - Since Beta 2
48 | - "Attempt to use a dehydrated detector" in routes, triggered by eventEmitter [#6786](https://github.com/angular/angular/issues/6786)
49 | - Since Beta 6
50 | - TypeError: viewFactory_0 is not a function [#7037](https://github.com/angular/angular/issues/7037)
51 | - Since Beta 16
52 | - Scheduler / tick not working for code with multiple async-events [#8251](https://github.com/angular/angular/issues/8251)
53 | - className property binding and "complex" expressions [#8244](https://github.com/angular/angular/issues/8244)
54 | - When injecting a non-imported class all of them are undefined [#8245](https://github.com/angular/angular/issues/8245)
55 | - ngFor + ChangeDetectionStrategy.OnPush = event handler not working [#8242](https://github.com/angular/angular/issues/8242)
56 | - UMD bundle missing ng.platform.common export [#8299](https://github.com/angular/angular/issues/8299)
57 |
58 | The currently recommended beta is the latest beta (16 at the time of this update).
59 |
60 | # API Stability
61 |
62 | With the release of beta, the Angular 2 team is hoping not to make breaking API changes. Some are likely to happen, but hopefully it should not require sweeping changes to your app. The only known proposed api breakages at this time are the router, and the animation API, as the current animation api is said to be temporary.
63 |
64 | # Documentation
65 |
66 | The general documentation and guide are very good and should be required reading. The API documentation is incomplete, and some examples are out of date. Overall the documentation is viable for everyday use.
67 |
68 | # Ecosystem
69 |
70 | The ecosystem is still just getting started. There will likely be a fair bit of work to catch up with Angular 1. That said, Angular 2 is largely free of the 'Angularisms' that made having Angular specific plugins a necessity. In many cases you can just use a vanilla js library with a thin component or directive wrapper you write yourself.
71 |
72 | # Community/Blogs/Support/Etc...
73 |
74 | The Angular 2 community is thriving, and a lot of information and tutorials can be found on the internet. The major problem is a lot of content covers the earlier alpha versions, and may not be directly applicable to the beta. The concepts are consistent from alpha to beta, and in most cases the only changes are small syntax changes.
75 |
76 | If you need support, the best place to look is the Angular 2 gitter: https://gitter.im/angular/angular. There are lots of people there who can help you out.
77 |
78 | # Do I have to use Typescript?
79 |
80 | Technically, no. You can use whatever you like. It is strongly recommended that you use TypeScript though.
81 |
82 | Documentation appears to be centered on TypeScript first, and the vast majority of examples are in it as well. Most users of Angular 2 have chosen to use Typescript, and that is what they will be familiar with.
83 |
84 | The angular team is also developing a plugin for TypeScript that will add Intellisense type hinting for Angular 2 specific constructs, for any editor that supports TypeScript integration.
85 |
86 | # Do I have to use a build system? What build system should I use?
87 |
88 | It is STRONGLY RECOMMENDED that you use a build system such as Webpack or SystemJs.
89 |
90 | Using a build system is not required or critical to the functioning of your Angular 2 app, however it is the long term plan, and to get all of the benefits of Angular 2 you will need a compile step. There are lots of bootstrap templates floating around github. Start your project with one of those and you won't have too much trouble.
91 |
92 | - Webpack Basic Starter: https://github.com/ocombe/ng2-webpack
93 | - Webpack Advanced Starter: https://github.com/AngularClass/angular2-webpack-starter
94 | - SystemJs Basic Starter: https://github.com/pkozlowski-opensource/ng2-play
95 | - SystemJs Advanced Starter: https://github.com/mgechev/angular2-seed
96 |
97 | # Router
98 |
99 | The Angular 2 router has some serious gaps at this time. Most of them have been worked around in some fashion in the Router section of this FAQ. It is stable, though there is a Proposed API change.
100 |
101 | # Internationalization
102 |
103 | As stated in the beta announcement, Internationalization is not yet complete. If you need this and are not willing to write your own internationalization module and port to the released one when it is done, Angular 2 may not be ready for you yet.
104 |
105 | # Animation
106 |
107 | Angular 2's animation module is very rudimentary and the release version is not yet ready. You will have to write your own animations, or wait.
108 |
109 | # Twitter Bootstrap/Material Design
110 |
111 | The Angular 2 specific version of Material is in alpha and available here: https://github.com/angular/material2
112 |
113 | There is not an official version of Angular 2 bootstrap, but there are some repos you can find if you search. I suggest looking at [ng-bootstrap/core](https://github.com/ng-bootstrap/core)
114 |
--------------------------------------------------------------------------------
/best-practices.md:
--------------------------------------------------------------------------------
1 | # Table of contents
2 |
3 | - [Proper use of EventEmitters](#proper-use-of-eventemitters)
4 | - [ElementRef, nativeElement and Renderer](#elementref-nativeelement-and-renderer)
5 | - [Don't use Subjects](#dont-use-subjects)
6 | - [Don't mix angular2 with 3rd libs](#dont-mix-angular2-with-3rd-libs)
7 | - [Don't use `ngAfterViewChecked` nor `ngAfterContentChecked`](#dont-use-ngafterviewchecked-nor-ngaftercontentchecked)
8 | - [Accessing elements in the view](#accessing-elements-in-the-view)
9 | - [Using @Injectable() in services](#using-injectable-in-services)
10 | - ~~[DynamicComponentLoader and loadAsRoot](#dynamiccomponentloader-and-loadasroot)~~ _DynamicComponentLoader has been deprecated, see [5297c9d9](https://github.com/angular/angular/commit/5297c9d9ccc6f8831d1656915e3d78e767022517)_
11 |
12 | ## Proper use of EventEmitters
13 |
14 | While EventEmitter extends from Subject, giving us the ability to subscribe, you should not count on this staying. [Ward Bell has stated](http://www.bennadel.com/blog/3038-eventemitter-is-an-rxjs-observable-stream-in-angular-2-beta-6.htm#comments_47949) that it is highly likely to be removed before release. EventEmitter is intended to ONLY be used with `@Output()`. If you want to subscribe just use a Subject directly.
15 |
16 | See more
17 | - [What is the proper use of an EventEmitter?](http://stackoverflow.com/questions/36076700/what-is-the-proper-use-of-an-eventemitter)
18 |
19 | ## ElementRef, nativeElement and Renderer
20 |
21 | Official documentation recommends against using `nativeElement` directly. The reason for this is because it is not WebWorker safe (It may also not work with Universal, and alternate renderer implementaitons). The preferred approach is to use the `nativeElement` with the Renderer. Of course, if you don't plan on using any of the cool stuff mentioned above, and are only targeting desktop browsers, then you should feel free to do whatever works; sometimes that's the only option.
22 |
23 | Consider the following examples
24 |
25 | ```js
26 |
27 | constructor(renderer: Renderer, elementRef: ElementRef) {}
28 |
29 |
30 | // Setting an attribute
31 | this.renderer.setElementAttribute(this.elementRef.nativeElement, 'contenteditable', 'true');
32 |
33 | // Setting a property
34 | this.renderer.setElementProperty(this.elementRef.nativeElement, 'checked', 'true');
35 |
36 | // Setting a style
37 | this.renderer.setElementStyle(this.elementRef.nativeElement, 'background-color', 'red');
38 |
39 | // Setting a class
40 | .my-css-class {}
41 | this.renderer.setElementClass(this.elementRef.nativeElement, 'my-css-class', true); // or false to remove
42 |
43 | // Invoking a method
44 | this.renderer.invokeElementMethod(this.elementRef.nativeElement, 'click', []); // Click doesn't receive any parameteres
45 | this.renderer.invokeElementMethod(this.elementRef.nativeElement, 'scrollIntoView', [false]); // 'scrollIntoView' accept true or false as parameter
46 |
47 | // Listen events in the element
48 | this.renderer.listen(this.elementRef.nativeElement, 'click', () => { /* callback */ });
49 |
50 | // Listen to global events
51 | this.renderer.listenGlobal('document', 'click', () => { /* callback */});
52 |
53 | ```
54 |
55 |
56 | See more
57 | - [What are some good alternatives to accessing the DOM using nativeElement in Angular2?](http://stackoverflow.com/questions/36108995/what-are-some-good-alternatives-to-accessing-the-dom-using-nativeelement-in-angu)
58 | - [Dynamically add event listener in Angular 2](http://stackoverflow.com/questions/35080387/dynamically-add-event-listener-in-angular-2)
59 |
60 |
61 | ## Don't use Subjects
62 |
63 | Subjects are a really powerful concept, they're an Observable that can also emit events. This power is easily abused though, and as such, it is better to try and avoid using Subjects whenever possible.
64 |
65 | There is a lot of discussion on why using Subjects is a bad idea, and the intent here is merely to be a summary. If you wish to learn more about subjects and why you shouldn't use them, please see the further reading at the end of this section.
66 |
67 | The gist of it is that Subjects are uncontrolled inputs to your observable sequence. You could be expecting numbers, and get a string instead. Controlling the input to your sequence is very important. This is why whenever possible you want to use an Observable helper instead of a Subject. Subjects are also hot, meaning that subcribers will only receive new events and not historical ones.
68 |
69 | Please also keep in mind, that if you use Observable.create and then hoist the input out of the create call, you have just made a subject.
70 |
71 | ### What should I use instead?
72 |
73 | First and foremost, if you already have an Observable, or something that can easily be observed (Controls, Events, etc..) you should just observe it, and extend the processing chain to meet your needs (making it cold or hot, etc..).
74 |
75 | Once you have exhausted all of your options for Obervable.x besides create and Subject, then you must if your entire sequence can be determined at creation. If this is the case, then use Observable.create, otherwise use a Subject.
76 |
77 | Further Reading:
78 | - (http://tomstechnicalblog.blogspot.ca/2016/03/rxjava-problem-with-subjects.html)
79 | - (http://davesexton.com/blog/post/To-Use-Subject-Or-Not-To-Use-Subject.aspx)
80 | - (https://medium.com/@benlesh/learning-observable-by-building-observable-d5da57405d87#.12a0rfxtt)
81 | - (https://medium.com/@benlesh/hot-vs-cold-observables-f8094ed53339#.x0q63ntrm)
82 |
83 |
84 | ## Don't mix Angular 2 with third party libraries
85 |
86 | Angular 2 works far better with third party libraries than Angular 1 did. In many cases, a library will work just fine with Angular 2. The biggest reasons not to use third party libraries is that they simply will not work optimally with Angular 2.
87 |
88 | Most javascript libraries rely on `addEventListener`, `setTimeouts` and others that trigger change detection in Angular 2. Triggering, or listening to events of 3rd party libs can trigger excesive change detection, and considerably decrease the perfomance of your application.
89 |
90 | On the other hand, these libraries can rely on event handling not patched by angular2, therefore these events will run outside angular2's zone causing change detection NOT to run!
91 |
92 | Additionally, Angular 2 wants templates to be compiled at build time, and not include the compiler in your redistributable (improving speed and load time). This means that while it is possible to use third party libraries in your templates, it is not possible to compile angular templates in your third party libs, as that would require exposing the compiler and bundling it.
93 |
94 | With all of that said, libraries that don't manipulate the dom, and don't need to be patched to work with zones can and do work perfectly with Angular 2, without patching or modification.
95 |
96 | If some cool library hasn't been ported to angular2, be the first to port it! Make yourself famous!
97 |
98 | See more
99 | - [Using JQuery With Angular 2.0](http://www.syntaxsuccess.com/viewarticle/using-jquery-with-angular-2.0)
100 |
101 |
102 | ## Don't use `ngAfterViewChecked` nor `ngAfterContentChecked`
103 |
104 | `ngAfterViewChecked` and `ngAfterContentChecked` are executed everytime change detection runs.
105 | Doing heavy calculations, adding/removing DOM or similar can end up in a very low performance application.
106 |
107 | Using Promises, setTimeouts, setIntervals, among others trigger change detection which executes these two lifecycle hooks. This combination can end in endless loops, memory leaks, etc...
108 |
109 | ## Accessing elements in the view
110 |
111 | Using `document` is discouraged, we cannot rely in it since it's not webworker safe. We [can't access the DOM within a WebWorker!](https://developer.mozilla.org/en-US/docs/Web/API/Web_Workers_API/Using_web_workers)
112 |
113 | To access elements in the view safely we can use
114 |
115 | `@ViewChild/@ViewChildren` with local variables or types.
116 |
117 | Using local variables
118 |
119 | ```js
120 | @Component({
121 | selector : 'my-app',
122 | template : `
123 |
Content inside my div
124 | `
125 | })
126 | class MyApp {
127 | @ViewChild('myDiv') myDiv: HTMLElement;
128 |
129 | ngAfterViewInit() {
130 | // this.myDiv
131 | }
132 | }
133 |
134 | ```
135 |
136 | Using types. Create a `@Directive` and attach it to the element
137 |
138 | ```js
139 | @Directive({
140 | selector : 'div'
141 | })
142 | class MyDiv {}
143 |
144 | @Component({
145 | selector : 'my-app',
146 | template : `
147 |
Content inside my div
148 | `,
149 | directives : [MyDiv]
150 | })
151 | class MyApp {
152 | @ViewChild(MyDiv) myDiv: MyDiv;
153 |
154 | ngAfterViewInit() {
155 | // this.myDiv
156 | }
157 | }
158 |
159 | ```
160 |
161 |
162 | ## Using @Injectable() in services
163 |
164 | Have you ever seen the error message `Cannot resolve all parameters for MyService(?). Make sure they all have valid type or annotations.`? Well, that's because you missed @Injectable()! Why do we need it really?
165 |
166 | >TypeScript generates metadata when the `emitDecoratorMetadata` option is set. However, that doesn’t mean that it generates metadata blindly for each and every class or method of our code. **TypeScript only generates metadata for a class, method, property or method/constructor parameter when a decorator is actually attached to that particular code**. Otherwise, a huge amount of unused metadata code would be generated, which not only affects file size, but it’d also have an impact on our application runtime.
167 |
168 | Portion extracted from [Injecting services in services in Angular 2](http://blog.thoughtram.io/angular/2015/09/17/resolve-service-dependencies-in-angular-2.html) by Pascal Precht.
169 |
170 | Do we really need @Injectable()? Not really, we could use any annotation, the point is to emit metadata and for that we could use any of them!
171 |
172 | This would work as well
173 |
174 | ```javascript
175 | class MyService {
176 | constructor(@Inject(Http) http: Http) {}
177 | }
178 | ```
179 |
180 | But the best practice is to use @Injectable()
181 |
182 | ```javascript
183 | @Injectable()
184 | class MyService {
185 | constructor(http: Http) {}
186 | }
187 | ```
188 |
189 |
190 | Angular2 is promoting [using @Injectable()](https://github.com/angular/angular.io/pull/1012#issuecomment-202326319) as a best practice, so the best option is to follow their recommendations.
191 |
192 |
193 |
194 | ## DynamicComponentLoader and loadAsRoot
195 |
196 | By @gdi2290, see his [comment](https://github.com/angular/angular/issues/6223#issuecomment-193908465)
197 | >loadAsRoot is used during [bootstrap](https://github.com/angular/angular/blob/2.0.0-beta.8/modules/angular2/src/core/application_ref.ts#L50) where angular is wiring everything up (di, cd etc) and by design it doesn't wire anything up that was rendered on the server (security reasons).
198 |
199 | So basically you shouldn't use `loadAsRoot` unless you're rewriting the bootstrap logic, taking into consideration the quote above. Use `loadNextToLocation` or `loadIntoLocation` instead.
200 |
--------------------------------------------------------------------------------