docs(aio): apply guidelines to ts-to-js - adapt for aio site (#16054)

This commit is contained in:
Kapunahele Wong 2017-04-28 18:34:00 -04:00 committed by Miško Hevery
parent 938406122e
commit b70b9606eb

View File

@ -1,11 +1,6 @@
@title # TypeScript to JavaScript
TypeScript to JavaScript
@intro
Convert Angular TypeScript examples into ES6 and ES5 JavaScript.
@description
## Introduction
Anything you can do with Angular in _TypeScript_, you can also do Anything you can do with Angular in _TypeScript_, you can also do
in JavaScript. Translating from one language to the other is mostly a in JavaScript. Translating from one language to the other is mostly a
@ -17,29 +12,8 @@ This cookbook contains recipes for translating _TypeScript_
code examples to _ES6_ and to _ES5_ so that JavaScript developers code examples to _ES6_ and to _ES5_ so that JavaScript developers
can read and write Angular apps in their preferred dialect. can read and write Angular apps in their preferred dialect.
Run and compare the live <live-example name="ts-to-js/ts">TypeScript</live-example> and <live-example name="ts-to-js/js">JavaScript</live-example>
{@a toc} code shown in this cookbook.
## Table of contents
* [_TypeScript_ to _ES6_ to _ES5_](guide/ts-to-js#from-ts)<br>
* [Modularity: imports and exports](guide/ts-to-js#modularity)<br>
* [Classes and Class Metadata](guide/ts-to-js#class-metadata)<br>
* [_ES5_ DSL](guide/ts-to-js#dsl)<br>
* [Interfaces](guide/ts-to-js#interfaces)<br>
* [Input and Output Metadata](guide/ts-to-js#io-decorators)<br>
* [Dependency Injection](guide/ts-to-js#dependency-injection)<br>
* [Host Binding](guide/ts-to-js#host-binding)<br>
* [View and Child Decorators](guide/ts-to-js#view-child-decorators)<br>
* [AOT compilation in _TypeScript_ Only](guide/ts-to-js#aot)<br>
**Run and compare the live <live-example name="ts-to-js/ts">TypeScript</live-example> and <live-example name="ts-to-js/js">JavaScript</live-example>
code shown in this cookbook.**
{@a from-ts}
## _TypeScript_ to _ES6_ to _ES5_ ## _TypeScript_ to _ES6_ to _ES5_
@ -49,11 +23,11 @@ _TypeScript_
_ES6 JavaScript_ is a superset of _ES5 JavaScript_. _ES5_ is the kind of JavaScript that runs natively in all modern browsers. _ES6 JavaScript_ is a superset of _ES5 JavaScript_. _ES5_ is the kind of JavaScript that runs natively in all modern browsers.
The transformation of _TypeScript_ code all the way down to _ES5_ code can be seen as "shedding" features. The transformation of _TypeScript_ code all the way down to _ES5_ code can be seen as "shedding" features.
The downgrade progression is The downgrade progression is as follows:
* _TypeScript_ to _ES6-with-decorators_ * _TypeScript_ to _ES6-with-decorators_.
* _ES6-with-decorators_ to _ES6-without-decorators_ ("_plain ES6_") * _ES6-with-decorators_ to _ES6-without-decorators_ ("_plain ES6_").
* _ES6-without-decorators_ to _ES5_ * _ES6-without-decorators_ to _ES5_.
When translating from _TypeScript_ to _ES6-with-decorators_, remove When translating from _TypeScript_ to _ES6-with-decorators_, remove
[class property access modifiers](http://www.typescriptlang.org/docs/handbook/classes.html#public-private-and-protected-modifiers) [class property access modifiers](http://www.typescriptlang.org/docs/handbook/classes.html#public-private-and-protected-modifiers)
@ -61,8 +35,7 @@ such as `public` and `private`.
Remove most of the Remove most of the
[type declarations](https://www.typescriptlang.org/docs/handbook/basic-types.html), [type declarations](https://www.typescriptlang.org/docs/handbook/basic-types.html),
such as `:string` and `:boolean` such as `:string` and `:boolean`
but **keep the constructor parameter types which are used for dependency injection**. but **keep the constructor parameter types, which are used for dependency injection**.
From _ES6-with-decorators_ to _plain ES6_, remove all From _ES6-with-decorators_ to _plain ES6_, remove all
[decorators](https://www.typescriptlang.org/docs/handbook/decorators.html) [decorators](https://www.typescriptlang.org/docs/handbook/decorators.html)
@ -78,46 +51,30 @@ Transpile with [Babel](https://babeljs.io/) using the `es2015` preset.
To use decorators and annotations with Babel, install the To use decorators and annotations with Babel, install the
[`angular2`](https://github.com/shuhei/babel-plugin-angular2-annotations) preset as well. [`angular2`](https://github.com/shuhei/babel-plugin-angular2-annotations) preset as well.
{@a modularity} {@a modularity}
## Importing and Exporting ## Importing and Exporting
### Importing Angular Code ### Importing Angular Code
In both _TypeScript_ and _ES6_, you import Angular classes, functions, and other members with _ES6_ `import` statements. In both _TypeScript_ and _ES6_, you import Angular classes, functions, and other members with _ES6_ `import` statements.
In _ES5_, you access the Angular entities of the [the Angular packages](glossary#scoped-package) In _ES5_, you access the Angular entities of the [the Angular packages](guide/glossary#scoped-package)
through the global `ng` object. through the global `ng` object.
Anything you can import from `@angular` is a nested member of this `ng` object: Anything you can import from `@angular` is a nested member of this `ng` object:
<code-tabs> <code-tabs>
<code-pane title="TypeScript" path="ts-to-js/ts/src/app/app.module.ts" region="ng2import"> <code-pane title="TypeScript" path="ts-to-js/ts/src/app/app.module.ts" region="ng2import">
</code-pane> </code-pane>
<code-pane title="ES6 JavaScript with decorators" path="ts-to-js/js-es6-decorators/src/app/app.module.es6" region="ng2import"> <code-pane title="ES6 JavaScript with decorators" path="ts-to-js/js-es6-decorators/src/app/app.module.es6" region="ng2import">
</code-pane> </code-pane>
<code-pane title="ES6 JavaScript" path="ts-to-js/js-es6/src/app/app.module.es6" region="ng2import"> <code-pane title="ES6 JavaScript" path="ts-to-js/js-es6/src/app/app.module.es6" region="ng2import">
</code-pane> </code-pane>
<code-pane title="ES5 JavaScript" path="ts-to-js/js/src/app/app.module.js" region="ng2import"> <code-pane title="ES5 JavaScript" path="ts-to-js/js/src/app/app.module.js" region="ng2import">
</code-pane> </code-pane>
</code-tabs> </code-tabs>
### Exporting application code
### Exporting Application Code
Each file in a _TypeScript_ or _ES6_ Angular application constitutes an _ES6_ module. Each file in a _TypeScript_ or _ES6_ Angular application constitutes an _ES6_ module.
When you want to make something available to other modules, you `export` it. When you want to make something available to other modules, you `export` it.
@ -127,18 +84,14 @@ In an Angular _ES5_ application, you load each file manually by adding a `<scrip
<div class="alert is-important"> <div class="alert is-important">
The order of `<script>` tags is often significant.
You must load a file that defines a public JavaScript entity before a file that references that entity.
The order of `<script>` tags is often significant.
You must load a file that defines a public JavaScript entity before a file that references that entity.
</div> </div>
The best practice in _ES5_ is to create a form of modularity that avoids polluting the global scope. The best practice in _ES5_ is to create a form of modularity that avoids polluting the global scope.
Add one application namespace object such as `app` to the global `document`. Add one application namespace object such as `app` to the global `document`.
Then each code file "exports" public entities by attaching them to that namespace object, e.g., `app.HeroComponent`. Then each code file "exports" public entities by attaching them to that namespace object, for example, `app.HeroComponent`.
You could factor a large application into several sub-namespaces You could factor a large application into several sub-namespaces
which leads to "exports" along the lines of `app.heroQueries.HeroComponent`. which leads to "exports" along the lines of `app.heroQueries.HeroComponent`.
@ -148,77 +101,45 @@ to limit unintentional leaking of private symbols into the global scope.
Here is a `HeroComponent` as it might be defined and "exported" in each of the four language variants. Here is a `HeroComponent` as it might be defined and "exported" in each of the four language variants.
<code-tabs> <code-tabs>
<code-pane title="TypeScript" path="ts-to-js/ts/src/app/hero.component.ts" region="appexport"> <code-pane title="TypeScript" path="ts-to-js/ts/src/app/hero.component.ts" region="appexport">
</code-pane> </code-pane>
<code-pane title="ES6 JavaScript with decorators" path="ts-to-js/js-es6-decorators/src/app/hero.component.es6" region="appexport"> <code-pane title="ES6 JavaScript with decorators" path="ts-to-js/js-es6-decorators/src/app/hero.component.es6" region="appexport">
</code-pane> </code-pane>
<code-pane title="ES6 JavaScript" path="ts-to-js/js-es6/src/app/hero.component.es6" region="appexport"> <code-pane title="ES6 JavaScript" path="ts-to-js/js-es6/src/app/hero.component.es6" region="appexport">
</code-pane> </code-pane>
<code-pane title="ES5 JavaScript" path="ts-to-js/js/src/app/hero.component.js" region="appexport"> <code-pane title="ES5 JavaScript" path="ts-to-js/js/src/app/hero.component.js" region="appexport">
</code-pane> </code-pane>
</code-tabs> </code-tabs>
### Importing application Code
### Importing Application Code
In _TypeScript_ and _ES6_ apps, you `import` things that have been exported from other modules. In _TypeScript_ and _ES6_ apps, you `import` things that have been exported from other modules.
In _ES5_ you use the shared namespace object to access "exported" entities from other files. In _ES5_ you use the shared namespace object to access "exported" entities from other files.
<code-tabs> <code-tabs>
<code-pane title="TypeScript" path="ts-to-js/ts/src/app/app.module.ts" region="appimport"> <code-pane title="TypeScript" path="ts-to-js/ts/src/app/app.module.ts" region="appimport">
</code-pane> </code-pane>
<code-pane title="ES6 JavaScript with decorators" path="ts-to-js/js-es6-decorators/src/app/app.module.es6" region="appimport"> <code-pane title="ES6 JavaScript with decorators" path="ts-to-js/js-es6-decorators/src/app/app.module.es6" region="appimport">
</code-pane> </code-pane>
<code-pane title="ES6 JavaScript" path="ts-to-js/js-es6/src/app/app.module.es6" region="appimport"> <code-pane title="ES6 JavaScript" path="ts-to-js/js-es6/src/app/app.module.es6" region="appimport">
</code-pane> </code-pane>
<code-pane title="ES5 JavaScript" path="ts-to-js/js/src/app/app.module.js" region="appimport"> <code-pane title="ES5 JavaScript" path="ts-to-js/js/src/app/app.module.js" region="appimport">
</code-pane> </code-pane>
</code-tabs> </code-tabs>
<div class="alert is-helpful"> <div class="alert is-helpful">
Alternatively, you can use a module loader such as Webpack or
Browserify in an Angular JavaScript project. In such a project, you would
Alternatively, you can use a module loader such as Webpack or use _CommonJS_ modules and the `require` function to load Angular framework code.
Browserify in an Angular JavaScript project. In such a project, you would Then use `module.exports` and `require` to export and import application code.
use _CommonJS_ modules and the `require` function to load Angular framework code.
Then use `module.exports` and `require` to export and import application code.
</div> </div>
{@a class-metadata} {@a class-metadata}
## Classes and Class Metadata ## Classes and Class Metadata
### Classes ### Classes
@ -229,7 +150,7 @@ Properties and method parameters of _TypeScript_ classes may be marked with the
`private`, `internal`, and `public`. `private`, `internal`, and `public`.
Remove these modifiers when translating to JavaScript. Remove these modifiers when translating to JavaScript.
Most type declarations (e.g, `:string` and `:boolean`) should be removed when translating to JavaScript. Most type declarations, for example, `:string` and `:boolean`, should be removed when translating to JavaScript.
When translating to _ES6-with-decorators_, ***do not remove types from constructor parameters!*** When translating to _ES6-with-decorators_, ***do not remove types from constructor parameters!***
Look for types in _TypeScript_ property declarations. Look for types in _TypeScript_ property declarations.
@ -243,29 +164,17 @@ In _ES6-without-decorators_, properties of classes must be assigned inside the c
_ES5_ JavaScript has no classes. _ES5_ JavaScript has no classes.
Use the constructor function pattern instead, adding methods to the prototype. Use the constructor function pattern instead, adding methods to the prototype.
<code-tabs> <code-tabs>
<code-pane title="TypeScript" path="ts-to-js/ts/src/app/hero.component.ts" region="class"> <code-pane title="TypeScript" path="ts-to-js/ts/src/app/hero.component.ts" region="class">
</code-pane> </code-pane>
<code-pane title="ES6 JavaScript with decorators" path="ts-to-js/js-es6-decorators/src/app/hero.component.es6" region="class"> <code-pane title="ES6 JavaScript with decorators" path="ts-to-js/js-es6-decorators/src/app/hero.component.es6" region="class">
</code-pane> </code-pane>
<code-pane title="ES6 JavaScript" path="ts-to-js/js-es6/src/app/hero.component.es6" region="class"> <code-pane title="ES6 JavaScript" path="ts-to-js/js-es6/src/app/hero.component.es6" region="class">
</code-pane> </code-pane>
<code-pane title="ES5 JavaScript" path="ts-to-js/js/src/app/hero.component.js" region="constructorproto"> <code-pane title="ES5 JavaScript" path="ts-to-js/js/src/app/hero.component.js" region="constructorproto">
</code-pane> </code-pane>
</code-tabs> </code-tabs>
### Metadata ### Metadata
When writing in _TypeScript_ or _ES6-with-decorators_, When writing in _TypeScript_ or _ES6-with-decorators_,
@ -281,70 +190,41 @@ In _ES5_, you also provide an `annotations` array but you attach it to the _cons
See these variations side-by-side: See these variations side-by-side:
<code-tabs> <code-tabs>
<code-pane title="TypeScript" path="ts-to-js/ts/src/app/hero.component.ts" region="metadata"> <code-pane title="TypeScript" path="ts-to-js/ts/src/app/hero.component.ts" region="metadata">
</code-pane> </code-pane>
<code-pane title="ES6 JavaScript with decorators" path="ts-to-js/js-es6-decorators/src/app/hero.component.es6" region="metadata"> <code-pane title="ES6 JavaScript with decorators" path="ts-to-js/js-es6-decorators/src/app/hero.component.es6" region="metadata">
</code-pane> </code-pane>
<code-pane title="ES6 JavaScript" path="ts-to-js/js-es6/src/app/hero.component.es6" region="metadata"> <code-pane title="ES6 JavaScript" path="ts-to-js/js-es6/src/app/hero.component.es6" region="metadata">
</code-pane> </code-pane>
<code-pane title="ES5 JavaScript" path="ts-to-js/js/src/app/hero.component.js" region="metadata"> <code-pane title="ES5 JavaScript" path="ts-to-js/js/src/app/hero.component.js" region="metadata">
</code-pane> </code-pane>
</code-tabs> </code-tabs>
## External template file
***External Template file***
A large component template is often kept in a separate template file. A large component template is often kept in a separate template file.
<code-example path="ts-to-js/ts/src/app/hero-title.component.html" title="src/app/hero-title.component.html" linenums="false"> <code-example path="ts-to-js/ts/src/app/hero-title.component.html" title="src/app/hero-title.component.html" linenums="false">
</code-example> </code-example>
The component, `HeroTitleComponent` in this case, then references the template file in its metadata `templateUrl` property:
The component (`HeroTitleComponent` in this case) then references the template file in its metadata `templateUrl` property:
<code-tabs> <code-tabs>
<code-pane title="TypeScript" path="ts-to-js/ts/src/app/hero-title.component.ts" region="templateUrl"> <code-pane title="TypeScript" path="ts-to-js/ts/src/app/hero-title.component.ts" region="templateUrl">
</code-pane> </code-pane>
<code-pane title="ES6 JavaScript with decorators" path="ts-to-js/js-es6-decorators/src/app/hero-title.component.es6" region="templateUrl"> <code-pane title="ES6 JavaScript with decorators" path="ts-to-js/js-es6-decorators/src/app/hero-title.component.es6" region="templateUrl">
</code-pane> </code-pane>
<code-pane title="ES6 JavaScript" path="ts-to-js/js-es6/src/app/hero-title.component.es6" region="templateUrl"> <code-pane title="ES6 JavaScript" path="ts-to-js/js-es6/src/app/hero-title.component.es6" region="templateUrl">
</code-pane> </code-pane>
<code-pane title="ES5 JavaScript" path="ts-to-js/js/src/app/hero-title.component.js" region="templateUrl"> <code-pane title="ES5 JavaScript" path="ts-to-js/js/src/app/hero-title.component.js" region="templateUrl">
</code-pane> </code-pane>
</code-tabs> </code-tabs>
Note that both the _TypeScript_ and _ES6_ `templateUrl` properties identify the location of the template file _relative to the component module_. Note that both the _TypeScript_ and _ES6_ `templateUrl` properties identify the location of the template file _relative to the component module_.
{@a dsl} {@a dsl}
## _ES5_ DSL ## _ES5_ DSL
This _ES5_ pattern of creating a constructor and annotating it with metadata is so common that Angular This _ES5_ pattern of creating a constructor and annotating it with metadata is so common that Angular
@ -353,47 +233,34 @@ as you would if you wrote in _TypeScript_ or _ES6-with-decorators_.
This _API_ (_Application Programming Interface_) is commonly known as the _ES5 DSL_ (_Domain Specific Language_). This _API_ (_Application Programming Interface_) is commonly known as the _ES5 DSL_ (_Domain Specific Language_).
Set an application namespace property (e.g., `app.HeroDslComponent`) to the result of an `ng.core.Component` function call. Set an application namespace property, for example, `app.HeroDslComponent`, to the result of an `ng.core.Component` function call.
Pass the same metadata object to `ng.core.Component` as you did before. Pass the same metadata object to `ng.core.Component` as you did before.
Then chain a call to the `Class` method which takes an object defining the class constructor and instance methods. Then chain a call to the `Class()` method which takes an object defining the class constructor and instance methods.
Here is an example of the `HeroComponent`, re-written with the DSL, Here is an example of the `HeroComponent`, re-written with the DSL,
next to the original _ES5_ version for comparison: next to the original _ES5_ version for comparison:
<code-tabs> <code-tabs>
<code-pane title="ES5 JavaScript with DSL" path="ts-to-js/js/src/app/hero.component.js" region="dsl"> <code-pane title="ES5 JavaScript with DSL" path="ts-to-js/js/src/app/hero.component.js" region="dsl">
</code-pane> </code-pane>
<code-pane title="ES5 JavaScript" path="ts-to-js/js/src/app/hero.component.js"> <code-pane title="ES5 JavaScript" path="ts-to-js/js/src/app/hero.component.js">
</code-pane> </code-pane>
</code-tabs> </code-tabs>
<div class="callout is-helpful"> <div class="callout is-helpful">
{@a name-constructor}
### Name the constructor
<header> A **named** constructor displays clearly in the console log
Name the constructor if the component throws a runtime error.
</header> An **unnamed** constructor displays as an anonymous function, for example, `class0`,
which is impossible to find in the source code.
A **named** constructor displays clearly in the console log
if the component throws a runtime error.
An **unnamed** constructor displays as an anonymous function (e.g., `class0`)
which is impossible to find in the source code.
</div> </div>
{@a getters-setters}
### Properties with getters and setters ### Properties with getters and setters
@ -402,11 +269,8 @@ Here's an example of a read-only _TypeScript_ property with a getter
that prepares a toggle-button label for the next clicked state: that prepares a toggle-button label for the next clicked state:
<code-example path="ts-to-js/ts/src/app/hero-queries.component.ts" region="defined-property" title="ts/src/app/hero-queries.component.ts" linenums="false"> <code-example path="ts-to-js/ts/src/app/hero-queries.component.ts" region="defined-property" title="ts/src/app/hero-queries.component.ts" linenums="false">
</code-example> </code-example>
This _TypeScript_ "getter" property is transpiled to an _ES5_ This _TypeScript_ "getter" property is transpiled to an _ES5_
<a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/defineProperty" <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/defineProperty"
title="Defined Properties">defined property</a>. title="Defined Properties">defined property</a>.
@ -415,10 +279,9 @@ but you can still create them by extracting the "class" prototype and
adding the _defined property_ in raw JavaScript like this: adding the _defined property_ in raw JavaScript like this:
<code-example path="ts-to-js/js/src/app/hero-queries.component.js" region="defined-property" title="js/src/app/hero-queries.component.ts" linenums="false"> <code-example path="ts-to-js/js/src/app/hero-queries.component.js" region="defined-property" title="js/src/app/hero-queries.component.ts" linenums="false">
</code-example> </code-example>
{@a dsl-other}
### DSL for other classes ### DSL for other classes
There are similar DSLs for other decorated classes. There are similar DSLs for other decorated classes.
@ -433,8 +296,6 @@ You can define a directive with `ng.core.Directive`:
}); });
</code-example> </code-example>
and a pipe with `ng.core.Pipe`: and a pipe with `ng.core.Pipe`:
<code-example> <code-example>
@ -443,19 +304,14 @@ and a pipe with `ng.core.Pipe`:
}).Class({ }).Class({
... ...
}); });
</code-example> </code-example>
{@a interfaces} {@a interfaces}
## Interfaces ## Interfaces
A _TypeScript_ interface helps ensure that a class implements the interface's members correctly. A _TypeScript_ interface helps ensure that a class implements the interface's members correctly.
We strongly recommend Angular interfaces where appropriate. Always try to use Angular interfaces where appropriate.
For example, the component class that implements the `ngOnInit` lifecycle hook method For example, the component class that implements the `ngOnInit` lifecycle hook method
should implement the `OnInit` interface. should implement the `OnInit` interface.
@ -463,37 +319,21 @@ _TypeScript_ interfaces exist for developer convenience and are not used by Angu
They have no physical manifestation in the generated JavaScript code. They have no physical manifestation in the generated JavaScript code.
Just implement the methods and ignore interfaces when translating code samples from _TypeScript_ to JavaScript. Just implement the methods and ignore interfaces when translating code samples from _TypeScript_ to JavaScript.
<code-tabs> <code-tabs>
<code-pane title="TypeScript" path="ts-to-js/ts/src/app/hero-lifecycle.component.ts"> <code-pane title="TypeScript" path="ts-to-js/ts/src/app/hero-lifecycle.component.ts">
</code-pane> </code-pane>
<code-pane title="ES6 JavaScript with decorators" path="ts-to-js/js-es6-decorators/src/app/hero-lifecycle.component.es6"> <code-pane title="ES6 JavaScript with decorators" path="ts-to-js/js-es6-decorators/src/app/hero-lifecycle.component.es6">
</code-pane> </code-pane>
<code-pane title="ES6 JavaScript" path="ts-to-js/js-es6/src/app/hero-lifecycle.component.es6"> <code-pane title="ES6 JavaScript" path="ts-to-js/js-es6/src/app/hero-lifecycle.component.es6">
</code-pane> </code-pane>
<code-pane title="ES5 JavaScript" path="ts-to-js/js/src/app/hero-lifecycle.component.js"> <code-pane title="ES5 JavaScript" path="ts-to-js/js/src/app/hero-lifecycle.component.js">
</code-pane> </code-pane>
<code-pane title="ES5 JavaScript with DSL" path="ts-to-js/js/src/app/hero-lifecycle.component.js" region="dsl"> <code-pane title="ES5 JavaScript with DSL" path="ts-to-js/js/src/app/hero-lifecycle.component.js" region="dsl">
</code-pane> </code-pane>
</code-tabs> </code-tabs>
{@a io-decorators} {@a io-decorators}
## Input and Output Metadata ## Input and Output Metadata
### Input and Output Decorators ### Input and Output Decorators
@ -511,35 +351,21 @@ there's nothing fundamentally new about adding another property.
But note that what would have been _separate_ `@Input` and `@Output` property decorators for each class property are But note that what would have been _separate_ `@Input` and `@Output` property decorators for each class property are
combined in the metadata `inputs` and `outputs` _arrays_. combined in the metadata `inputs` and `outputs` _arrays_.
<code-tabs> <code-tabs>
<code-pane title="TypeScript" path="ts-to-js/ts/src/app/confirm.component.ts"> <code-pane title="TypeScript" path="ts-to-js/ts/src/app/confirm.component.ts">
</code-pane> </code-pane>
<code-pane title="ES6 JavaScript with decorators" path="ts-to-js/js-es6-decorators/src/app/confirm.component.es6"> <code-pane title="ES6 JavaScript with decorators" path="ts-to-js/js-es6-decorators/src/app/confirm.component.es6">
</code-pane> </code-pane>
<code-pane title="ES6 JavaScript" path="ts-to-js/js-es6/src/app/confirm.component.es6"> <code-pane title="ES6 JavaScript" path="ts-to-js/js-es6/src/app/confirm.component.es6">
</code-pane> </code-pane>
<code-pane title="ES5 JavaScript" path="ts-to-js/js/src/app/confirm.component.js"> <code-pane title="ES5 JavaScript" path="ts-to-js/js/src/app/confirm.component.js">
</code-pane> </code-pane>
<code-pane title="ES5 JavaScript with DSL" path="ts-to-js/js/src/app/confirm.component.js" region="dsl"> <code-pane title="ES5 JavaScript with DSL" path="ts-to-js/js/src/app/confirm.component.js" region="dsl">
</code-pane> </code-pane>
</code-tabs> </code-tabs>
In the previous example, one of the public-facing binding names, `cancelMsg`,
differs from the corresponding class property name, `notOkMsg`.
In the previous example, one of the public-facing binding names (`cancelMsg`)
differs from the corresponding class property name (`notOkMsg`).
That's OK but you must tell Angular about it so that it can map an external binding of `cancelMsg` That's OK but you must tell Angular about it so that it can map an external binding of `cancelMsg`
to the component's `notOkMsg` property. to the component's `notOkMsg` property.
@ -548,67 +374,54 @@ you specify the special binding name in the argument to the property decorator.
In _ES5_ and _plain ES6_ code, convey this pairing with the `propertyName: bindingName` syntax in the class metadata. In _ES5_ and _plain ES6_ code, convey this pairing with the `propertyName: bindingName` syntax in the class metadata.
{@a dependency-injection}
## Dependency injection
## Dependency Injection
Angular relies heavily on [Dependency Injection](guide/dependency-injection) to provide services to the objects it creates. Angular relies heavily on [Dependency Injection](guide/dependency-injection) to provide services to the objects it creates.
When Angular creates a new component, directive, pipe or another service, When Angular creates a new component, directive, pipe or another service,
it sets the class constructor parameters to instances of services provided by an _Injector_. it sets the class constructor parameters to instances of services provided by an _Injector_.
The developer must tell Angular what to inject into each parameter. The developer must tell Angular what to inject into each parameter.
### Injection by Class Type {@a injection-class-type}
### Injection by class type
The easiest and most popular technique in _TypeScript_ and _ES6-with-decorators_ is to set the constructor parameter type The easiest and most popular technique in _TypeScript_ and _ES6-with-decorators_ is to set the constructor parameter type
to the class associated with the service to inject. to the class associated with the service to inject.
The _TypeScript_ transpiler writes parameter type information into the generated JavaScript. The _TypeScript_ transpiler writes parameter type information into the generated JavaScript.
Angular reads that information at runtime and locates the corresponding service in the appropriate _Injector_.. Angular reads that information at runtime and locates the corresponding service in the appropriate _Injector_.
The _ES6-with-decorators_ transpiler does essentially the same thing using the same parameter-typing syntax. The _ES6-with-decorators_ transpiler does essentially the same thing using the same parameter-typing syntax.
_ES5_ and _plain ES6_ lack types so you must identify "injectables" by attaching a **`parameters`** array to the constructor function. _ES5_ and _plain ES6_ lack types so you must identify "injectables" by attaching a **`parameters`** array to the constructor function.
Each item in the array specifies the service's injection token. Each item in the array specifies the service's injection token.
As with _TypeScript_ the most popular token is a class, As with _TypeScript_, the most popular token is a class,
or rather a _constructor function_ that represents a class in _ES5_ and _plain ES6_. or rather a _constructor function_ that represents a class in _ES5_ and _plain ES6_.
The format of the `parameters` array varies: The format of the `parameters` array varies:
* _plain ES6_ &mdash; nest each constructor function in a sub-array. * _Plain ES6_&mdash;nest each constructor function in a sub-array.
* _ES5_&mdash;simply list the constructor functions.
* _ES5_ &mdash; simply list the constructor functions.
When writing with _ES5 DSL_, set the `Class.constructor` property to When writing with _ES5 DSL_, set the `Class.constructor` property to
an array whose first parameters are the injectable constructor functions and whose an array whose first parameters are the injectable constructor functions and whose
last parameter is the class constructor itself. last parameter is the class constructor itself.
This format should be familiar to AngularJS developers. This format should be familiar to AngularJS developers.
<code-tabs> <code-tabs>
<code-pane title="TypeScript" path="ts-to-js/ts/src/app/hero-di.component.ts"> <code-pane title="TypeScript" path="ts-to-js/ts/src/app/hero-di.component.ts">
</code-pane> </code-pane>
<code-pane title="ES6 JavaScript with decorators" path="ts-to-js/js-es6-decorators/src/app/hero-di.component.es6"> <code-pane title="ES6 JavaScript with decorators" path="ts-to-js/js-es6-decorators/src/app/hero-di.component.es6">
</code-pane> </code-pane>
<code-pane title="ES6 JavaScript" path="ts-to-js/js-es6/src/app/hero-di.component.es6"> <code-pane title="ES6 JavaScript" path="ts-to-js/js-es6/src/app/hero-di.component.es6">
</code-pane> </code-pane>
<code-pane title="ES5 JavaScript" path="ts-to-js/js/src/app/hero-di.component.js"> <code-pane title="ES5 JavaScript" path="ts-to-js/js/src/app/hero-di.component.js">
</code-pane> </code-pane>
<code-pane title="ES5 JavaScript with DSL" path="ts-to-js/js/src/app/hero-di.component.js" region="dsl"> <code-pane title="ES5 JavaScript with DSL" path="ts-to-js/js/src/app/hero-di.component.js" region="dsl">
</code-pane> </code-pane>
</code-tabs> </code-tabs>
### Injection with the @Inject decorator ### Injection with the @Inject decorator
Sometimes the dependency injection token isn't a class or constructor function. Sometimes the dependency injection token isn't a class or constructor function.
@ -620,40 +433,25 @@ In the following example, the token is the string `'heroName'`.
The other JavaScript dialects add a `parameters` array to the class contructor function. The other JavaScript dialects add a `parameters` array to the class contructor function.
Each item constains a new instance of `Inject`: Each item constains a new instance of `Inject`:
* _plain ES6_ &mdash; each item is a new instance of `Inject(token)` in a sub-array. * _Plain ES6_&mdash;each item is a new instance of `Inject(token)` in a sub-array.
* _ES5_&mdash;simply list the string tokens.
* _ES5_ &mdash; simply list the string tokens.
When writing with _ES5 DSL_, set the `Class.constructor` property to a function definition When writing with _ES5 DSL_, set the `Class.constructor` property to a function definition
array as before. Create a new instance of `ng.core.Inject(token)` for each parameter. array as before. Create a new instance of `ng.core.Inject(token)` for each parameter.
<code-tabs> <code-tabs>
<code-pane title="TypeScript" path="ts-to-js/ts/src/app/hero-di-inject.component.ts"> <code-pane title="TypeScript" path="ts-to-js/ts/src/app/hero-di-inject.component.ts">
</code-pane> </code-pane>
<code-pane title="ES6 JavaScript with decorators" path="ts-to-js/js-es6-decorators/src/app/hero-di-inject.component.es6"> <code-pane title="ES6 JavaScript with decorators" path="ts-to-js/js-es6-decorators/src/app/hero-di-inject.component.es6">
</code-pane> </code-pane>
<code-pane title="ES6 JavaScript" path="ts-to-js/js-es6/src/app/hero-di-inject.component.es6"> <code-pane title="ES6 JavaScript" path="ts-to-js/js-es6/src/app/hero-di-inject.component.es6">
</code-pane> </code-pane>
<code-pane title="ES5 JavaScript" path="ts-to-js/js/src/app/hero-di-inject.component.js"> <code-pane title="ES5 JavaScript" path="ts-to-js/js/src/app/hero-di-inject.component.js">
</code-pane> </code-pane>
<code-pane title="ES5 JavaScript with DSL" path="ts-to-js/js/src/app/hero-di-inject.component.js" region="dsl"> <code-pane title="ES5 JavaScript with DSL" path="ts-to-js/js/src/app/hero-di-inject.component.js" region="dsl">
</code-pane> </code-pane>
</code-tabs> </code-tabs>
### Additional Injection Decorators ### Additional Injection Decorators
You can qualify injection behavior with injection decorators from `@angular/core`. You can qualify injection behavior with injection decorators from `@angular/core`.
@ -661,67 +459,46 @@ You can qualify injection behavior with injection decorators from `@angular/core
In _TypeScript_ and _ES6-with-decorators_, In _TypeScript_ and _ES6-with-decorators_,
you precede the constructor parameters with injection qualifiers such as: you precede the constructor parameters with injection qualifiers such as:
* [`@Optional`](api/core/index/Optional-decorator) sets the parameter to `null` if the service is missing * [`@Optional`](api/core/index/Optional-decorator) sets the parameter to `null` if the service is missing.
* [`@Attribute`](api/core/index/Attribute-interface) to inject a host element attribute value * [`@Attribute`](api/core/index/Attribute-interface) to inject a host element attribute value.
* [`@ContentChild`](api/core/index/ContentChild-decorator) to inject a content child * [`@ContentChild`](api/core/index/ContentChild-decorator) to inject a content child.
* [`@ViewChild`](api/core/index/ViewChild-decorator) to inject a view child * [`@ViewChild`](api/core/index/ViewChild-decorator) to inject a view child.
* [`@Host`](api/core/index/Host-decorator) to inject a service in this component or its host * [`@Host`](api/core/index/Host-decorator) to inject a service in this component or its host.
* [`@SkipSelf`](api/core/index/SkipSelf-decorator) to inject a service provided in an ancestor of this component * [`@SkipSelf`](api/core/index/SkipSelf-decorator) to inject a service provided in an ancestor of this component.
In _plain ES6_ and _ES5_, create an instance of the equivalent injection qualifier in a nested array within the `parameters` array. In _plain ES6_ and _ES5_, create an instance of the equivalent injection qualifier in a nested array within the `parameters` array.
For example, you'd write `new Optional()` in _plain ES6_ and `new ng.core.Optional()` in _ES5_. For example, you'd write `new Optional()` in _plain ES6_ and `new ng.core.Optional()` in _ES5_.
When writing with _ES5 DSL_, set the `Class.constructor` property to a function definition When writing with _ES5 DSL_, set the `Class.constructor` property to a function definition
array as before. Use a nested array to define a parameter's complete injection specification. array as before. Use a nested array to define a parameter's complete injection specification.
<code-tabs> <code-tabs>
<code-pane title="TypeScript" path="ts-to-js/ts/src/app/hero-title.component.ts"> <code-pane title="TypeScript" path="ts-to-js/ts/src/app/hero-title.component.ts">
</code-pane> </code-pane>
<code-pane title="ES6 JavaScript with decorators" path="ts-to-js/js-es6-decorators/src/app/hero-title.component.es6"> <code-pane title="ES6 JavaScript with decorators" path="ts-to-js/js-es6-decorators/src/app/hero-title.component.es6">
</code-pane> </code-pane>
<code-pane title="ES6 JavaScript" path="ts-to-js/js-es6/src/app/hero-title.component.es6"> <code-pane title="ES6 JavaScript" path="ts-to-js/js-es6/src/app/hero-title.component.es6">
</code-pane> </code-pane>
<code-pane title="ES5 JavaScript" path="ts-to-js/js/src/app/hero-title.component.js"> <code-pane title="ES5 JavaScript" path="ts-to-js/js/src/app/hero-title.component.js">
</code-pane> </code-pane>
<code-pane title="ES5 JavaScript with DSL" path="ts-to-js/js/src/app/hero-title.component.js" region="dsl"> <code-pane title="ES5 JavaScript with DSL" path="ts-to-js/js/src/app/hero-title.component.js" region="dsl">
</code-pane> </code-pane>
</code-tabs> </code-tabs>
<div class="l-sub-section"> <div class="l-sub-section">
In the example above, there is no provider for the `'titlePrefix'` token.
Without `@Optional()`, Angular would raise an error.
In the example above, there is no provider for the `'titlePrefix'` token. With `@Optional()`, Angular sets the constructor parameter to `null`
Without `Optional`, Angular would raise an error. and the component displays the title without a prefix.
With `Optional`, Angular sets the constructor parameter to `null`
and the component displays the title without a prefix.
</div> </div>
{@a host-binding} {@a host-binding}
## Host Binding ## Host Binding
Angular supports bindings to properties and events of the _host element_ which is the
Angular supports bindings to properties and events of the _host element_, which is the
element whose tag matches the component selector. element whose tag matches the component selector.
### Host Decorators ### Host Decorators
@ -742,78 +519,51 @@ The `host` value is an object whose properties are host property and listener b
or `(event)` for host listeners. or `(event)` for host listeners.
* Each value identifies the corresponding component property or method. * Each value identifies the corresponding component property or method.
<code-tabs> <code-tabs>
<code-pane title="TypeScript" path="ts-to-js/ts/src/app/hero-host.component.ts"> <code-pane title="TypeScript" path="ts-to-js/ts/src/app/hero-host.component.ts">
</code-pane> </code-pane>
<code-pane title="ES6 JavaScript with decorators" path="ts-to-js/js-es6-decorators/src/app/hero-host.component.es6"> <code-pane title="ES6 JavaScript with decorators" path="ts-to-js/js-es6-decorators/src/app/hero-host.component.es6">
</code-pane> </code-pane>
<code-pane title="ES6 JavaScript" path="ts-to-js/js-es6/src/app/hero-host.component.es6"> <code-pane title="ES6 JavaScript" path="ts-to-js/js-es6/src/app/hero-host.component.es6">
</code-pane> </code-pane>
<code-pane title="ES5 JavaScript" path="ts-to-js/js/src/app/hero-host.component.js"> <code-pane title="ES5 JavaScript" path="ts-to-js/js/src/app/hero-host.component.js">
</code-pane> </code-pane>
<code-pane title="ES5 JavaScript with DSL" path="ts-to-js/js/src/app/hero-host.component.js" region="dsl"> <code-pane title="ES5 JavaScript with DSL" path="ts-to-js/js/src/app/hero-host.component.js" region="dsl">
</code-pane> </code-pane>
</code-tabs> </code-tabs>
### Host Metadata ### Host Metadata
Some developers prefer to specify host properties and listeners Some developers prefer to specify host properties and listeners
in the component metadata. in the component metadata.
They'd _rather_ do it the way you _must_ do it _ES5_ and _plain ES6_. They'd _rather_ do it the way you _must_ do it _ES5_ and _plain ES6_.
The following re-implementation of the `HeroComponent` reminds us that _any property metadata decorator_ The following re-implementation of the `HeroComponent` shows that _any property metadata decorator_
can be expressed as component or directive metadata in both _TypeScript_ and _ES6-with-decorators_. can be expressed as component or directive metadata in both _TypeScript_ and _ES6-with-decorators_.
These particular _TypeScript_ and _ES6_ code snippets happen to be identical. These particular _TypeScript_ and _ES6_ code snippets happen to be identical.
<code-tabs> <code-tabs>
<code-pane title="TypeScript" path="ts-to-js/ts/src/app/hero-host-meta.component.ts"> <code-pane title="TypeScript" path="ts-to-js/ts/src/app/hero-host-meta.component.ts">
</code-pane> </code-pane>
<code-pane title="ES6 JavaScript with decorators" path="ts-to-js/js-es6-decorators/src/app/hero-host-meta.component.es6"> <code-pane title="ES6 JavaScript with decorators" path="ts-to-js/js-es6-decorators/src/app/hero-host-meta.component.es6">
</code-pane> </code-pane>
</code-tabs> </code-tabs>
{@a view-child-decorators} {@a view-child-decorators}
### View and Child Decorators ### View and Child Decorators
Several _property_ decorators query a component's nested view and content components. Several _property_ decorators query a component's nested view and content components.
<div class="l-sub-section"> <div class="l-sub-section">
_View_ children are associated with element tags that appear _within_ the component's template.
_Content_ children are associated with elements that appear _between_ the component's element tags;
_View_ children are associated with element tags that appear _within_ the component's template. they are projected into an `<ng-content>` slot in the component's template.
_Content_ children are associated with elements that appear _between_ the component's element tags;
they are projected into an `<ng-content>` slot in the component's template.
</div> </div>
The [`@ViewChild`](api/core/index/ViewChild-decorator) and The [`@ViewChild`](api/core/index/ViewChild-decorator) and
[`@ViewChildren`](api/core/index/ViewChildren-decorator) property decorators [`@ViewChildren`](api/core/index/ViewChildren-decorator) property decorators
allow a component to query instances of other components that are used in allow a component to query instances of other components that are used in
@ -822,32 +572,20 @@ its view.
In _ES5_ and _ES6_, you access a component's view children by adding a `queries` property to the component metadata. In _ES5_ and _ES6_, you access a component's view children by adding a `queries` property to the component metadata.
The `queries` property value is a hash map. The `queries` property value is a hash map.
* each _key_ is the name of a component property that will hold the view child or children. * Each _key_ is the name of a component property that will hold the view child or children.
* each _value_ is a new instance of either `ViewChild` or `ViewChildren`. * Each _value_ is a new instance of either `ViewChild` or `ViewChildren`.
<code-tabs> <code-tabs>
<code-pane title="TypeScript" path="ts-to-js/ts/src/app/hero-queries.component.ts" region="view"> <code-pane title="TypeScript" path="ts-to-js/ts/src/app/hero-queries.component.ts" region="view">
</code-pane> </code-pane>
<code-pane title="ES6 JavaScript with decorators" path="ts-to-js/js-es6-decorators/src/app/hero-queries.component.es6" region="view"> <code-pane title="ES6 JavaScript with decorators" path="ts-to-js/js-es6-decorators/src/app/hero-queries.component.es6" region="view">
</code-pane> </code-pane>
<code-pane title="ES6 JavaScript" path="ts-to-js/js-es6/src/app/hero-queries.component.es6" region="view"> <code-pane title="ES6 JavaScript" path="ts-to-js/js-es6/src/app/hero-queries.component.es6" region="view">
</code-pane> </code-pane>
<code-pane title="ES5 JavaScript with DSL" path="ts-to-js/js/src/app/hero-queries.component.js" region="view"> <code-pane title="ES5 JavaScript with DSL" path="ts-to-js/js/src/app/hero-queries.component.js" region="view">
</code-pane> </code-pane>
</code-tabs> </code-tabs>
The [`@ContentChild`](api/core/index/ContentChild-decorator) and The [`@ContentChild`](api/core/index/ContentChild-decorator) and
[`@ContentChildren`](api/core/index/ContentChildren-decorator) property decorators [`@ContentChildren`](api/core/index/ContentChildren-decorator) property decorators
allow a component to query instances of other components that have been projected allow a component to query instances of other components that have been projected
@ -856,49 +594,30 @@ into its view from elsewhere.
They can be added in the same way as [`@ViewChild`](api/core/index/ViewChild-decorator) and They can be added in the same way as [`@ViewChild`](api/core/index/ViewChild-decorator) and
[`@ViewChildren`](api/core/index/ViewChildren-decorator). [`@ViewChildren`](api/core/index/ViewChildren-decorator).
<code-tabs> <code-tabs>
<code-pane title="TypeScript" path="ts-to-js/ts/src/app/hero-queries.component.ts" region="content"> <code-pane title="TypeScript" path="ts-to-js/ts/src/app/hero-queries.component.ts" region="content">
</code-pane> </code-pane>
<code-pane title="ES6 JavaScript with decorators" path="ts-to-js/js-es6-decorators/src/app/hero-queries.component.es6" region="content"> <code-pane title="ES6 JavaScript with decorators" path="ts-to-js/js-es6-decorators/src/app/hero-queries.component.es6" region="content">
</code-pane> </code-pane>
<code-pane title="ES6 JavaScript" path="ts-to-js/js-es6/src/app/hero-queries.component.es6" region="content"> <code-pane title="ES6 JavaScript" path="ts-to-js/js-es6/src/app/hero-queries.component.es6" region="content">
</code-pane> </code-pane>
<code-pane title="ES5 JavaScript with DSL" path="ts-to-js/js/src/app/hero-queries.component.js" region="content"> <code-pane title="ES5 JavaScript with DSL" path="ts-to-js/js/src/app/hero-queries.component.js" region="content">
</code-pane> </code-pane>
</code-tabs> </code-tabs>
<div class="alert is-helpful"> <div class="alert is-helpful">
In _TypeScript_ and _ES6-with-decorators_ you can also use the `queries` metadata
instead of the `@ViewChild` and `@ContentChild` property decorators.
In _TypeScript_ and _ES6-with-decorators_ you can also use the `queries` metadata
instead of the `@ViewChild` and `@ContentChild` property decorators.
</div> </div>
{@a aot} {@a aot}
## AOT Compilation in _TypeScript_ only ## AOT Compilation in _TypeScript_ only
Angular offers two modes of template compilation, JIT (_Just-in-Time_) and Angular offers two modes of template compilation, JIT (_just-in-time_) and
[AOT (_Ahead-of-Time_)](guide/aot-compiler). [AOT (_ahead-of-time_)](guide/aot-compiler).
Currently the AOT compiler only works with _TypeScript_ applications because, in part, it generates Currently the AOT compiler only works with _TypeScript_ applications because, in part, it generates
_TypeScript_ files as an intermediate result. _TypeScript_ files as an intermediate result.
**AOT is not an option for pure JavaScript applications** at this time. **AOT is not an option for pure JavaScript applications** at this time.