2016-03-16 12:01:33 -04:00
|
|
|
|
include ../../../../_includes/_util-fns
|
|
|
|
|
|
|
|
|
|
:marked
|
|
|
|
|
Everything that we can do in Angular 2 in TypeScript, we can also do
|
|
|
|
|
in JavaScript. Translating from one language to the other is mostly a
|
|
|
|
|
matter of changing the way we organize our code and the way we access
|
|
|
|
|
Angular 2 APIs.
|
2016-05-16 06:20:52 -04:00
|
|
|
|
|
|
|
|
|
所有能在TypeScript环境里面做的Angular 2事情,我们都能在JavaScript里面实现。
|
|
|
|
|
从一个语言翻译到另一个语言最多只能改变我们对源代码的管理方法和如何访问Angular 2的API。
|
2016-03-16 12:01:33 -04:00
|
|
|
|
|
|
|
|
|
Since TypeScript is a popular language option in Angular 2, many of the
|
|
|
|
|
code examples you see on the Internet as well as on this site are written
|
|
|
|
|
in TypeScript. This cookbook contains recipes for translating these kinds of
|
|
|
|
|
code examples to ES5, so that they can be applied to Angular 2 JavaScript
|
|
|
|
|
applications.
|
2016-05-16 06:20:52 -04:00
|
|
|
|
|
2016-05-16 10:15:34 -04:00
|
|
|
|
因为TypeScript是一个很受欢迎的Angular 2的语言选择,你在网络上和本站看到的很多代码例子
|
2016-05-22 07:26:23 -04:00
|
|
|
|
都是以TypeScript编写的。本烹饪宝典包含如何把这些代码编译到ES5的食谱,这样它们可以被应用
|
2016-05-16 10:15:34 -04:00
|
|
|
|
到Angular 2的JavaScript应用程序里。
|
2016-05-16 06:20:52 -04:00
|
|
|
|
|
2016-03-16 12:01:33 -04:00
|
|
|
|
|
|
|
|
|
<a id="toc"></a>
|
|
|
|
|
:marked
|
|
|
|
|
## Table of contents
|
2016-05-16 10:15:34 -04:00
|
|
|
|
|
|
|
|
|
## 目录
|
2016-03-16 12:01:33 -04:00
|
|
|
|
|
|
|
|
|
[Modularity: imports and exports](#modularity)
|
2016-05-16 10:15:34 -04:00
|
|
|
|
|
|
|
|
|
[模块化:导入和导出](#modularity)
|
2016-03-16 12:01:33 -04:00
|
|
|
|
|
|
|
|
|
[Classes and Class Metadata](#class-metadata)
|
|
|
|
|
|
2016-05-16 10:15:34 -04:00
|
|
|
|
[类和类元数据](#class-metadata)
|
|
|
|
|
|
2016-03-16 12:01:33 -04:00
|
|
|
|
[Input and Output Metadata](#property-metadata)
|
|
|
|
|
|
2016-05-16 10:15:34 -04:00
|
|
|
|
[导入和导出元数据](#property-metadata)
|
|
|
|
|
|
2016-03-16 12:01:33 -04:00
|
|
|
|
[Dependency Injection](#dependency-injection)
|
|
|
|
|
|
2016-05-16 10:15:34 -04:00
|
|
|
|
[依赖注入](#dependency-injection)
|
|
|
|
|
|
2016-03-16 12:01:33 -04:00
|
|
|
|
[Host and Query Metadata](#other-property-metadata)
|
2016-05-16 10:15:34 -04:00
|
|
|
|
|
|
|
|
|
[宿主和查询元素据](#other-property-metadata)
|
2016-03-16 12:01:33 -04:00
|
|
|
|
|
|
|
|
|
**Run and compare the live [TypeScript](/resources/live-examples/cb-ts-to-js/ts/plnkr.html) and
|
|
|
|
|
[JavaScript](/resources/live-examples/cb-ts-to-js/js/plnkr.html) code shown in this cookbook.**
|
2016-05-16 10:15:34 -04:00
|
|
|
|
|
2016-05-22 07:26:23 -04:00
|
|
|
|
**运行并比较本烹饪宝典里面的在线[TypeScript](/resources/live-examples/cb-ts-to-js/ts/plnkr.html)和[JavaScript](/resources/live-examples/cb-ts-to-js/js/plnkr.html)代码**
|
2016-03-16 12:01:33 -04:00
|
|
|
|
|
|
|
|
|
a(id="modularity")
|
|
|
|
|
.l-main-section
|
|
|
|
|
:marked
|
|
|
|
|
## Importing and Exporting
|
|
|
|
|
|
2016-05-16 10:15:34 -04:00
|
|
|
|
## 导入和导出
|
|
|
|
|
|
2016-03-16 12:01:33 -04:00
|
|
|
|
- var top="vertical-align:top"
|
|
|
|
|
table(width="100%")
|
|
|
|
|
col(width="50%")
|
|
|
|
|
col(width="50%")
|
|
|
|
|
tr
|
|
|
|
|
th TypeScript
|
|
|
|
|
th ES5 JavaScript
|
|
|
|
|
tr(style=top)
|
|
|
|
|
td
|
|
|
|
|
:marked
|
|
|
|
|
### Importing Angular 2 Code
|
|
|
|
|
|
2016-05-16 10:15:34 -04:00
|
|
|
|
### 导入Angular 2代码
|
|
|
|
|
|
2016-03-16 12:01:33 -04:00
|
|
|
|
In TypeScript code, Angular 2 classes, functions, and other members
|
|
|
|
|
are imported with TypeScript `import` statements:
|
2016-05-16 10:15:34 -04:00
|
|
|
|
|
|
|
|
|
在TypeScript代码中,Angular 2是利用TypeScript的`import`声明来导入类、函数和其他成员的。
|
2016-03-16 12:01:33 -04:00
|
|
|
|
|
|
|
|
|
+makeExample('cb-ts-to-js/ts/app/main.ts', 'ng2import')(format="." )
|
|
|
|
|
|
|
|
|
|
td
|
|
|
|
|
:marked
|
|
|
|
|
### Accessing Angular 2 Code through the ng global
|
2016-05-16 10:15:34 -04:00
|
|
|
|
|
|
|
|
|
### 通过全局ng来访问Angular 2代码
|
2016-03-16 12:01:33 -04:00
|
|
|
|
|
|
|
|
|
In JavaScript code, when using
|
2016-04-27 14:28:22 -04:00
|
|
|
|
[the Angular 2 packages](../glossary.html#!#scoped-package),
|
2016-03-16 12:01:33 -04:00
|
|
|
|
we can access Angular code through the global `ng` object. In the
|
|
|
|
|
nested members of this object we'll find everything we would import
|
|
|
|
|
from `angular2` in TypeScript:
|
2016-05-16 10:15:34 -04:00
|
|
|
|
|
|
|
|
|
在JavaScript代码中,当使用[Angular 2库](../glossary.html#!#scoped-package)时,
|
|
|
|
|
我们可以通过全局的`ng`对象来访问Angular代码。在这个对象嵌套很多成员中,我们能找到所有在TypeScript里面导入的`angular2`
|
2016-03-16 12:01:33 -04:00
|
|
|
|
|
|
|
|
|
+makeExample('cb-ts-to-js/js/app/main.js', 'ng2import')(format="." )
|
|
|
|
|
|
|
|
|
|
tr(style=top)
|
|
|
|
|
td
|
|
|
|
|
:marked
|
|
|
|
|
### Importing and Exporting Application Code
|
|
|
|
|
|
2016-05-16 10:15:34 -04:00
|
|
|
|
### 导入和导出应用程序代码
|
|
|
|
|
|
2016-03-16 12:01:33 -04:00
|
|
|
|
Each file in an Angular 2 TypeScript application constitutes a
|
|
|
|
|
TypeScript module. When we want to make something from a module available
|
|
|
|
|
to other modules, we `export` it.
|
2016-05-16 10:15:34 -04:00
|
|
|
|
|
|
|
|
|
在Angular 2 TypeScript应用里,每个文件组成一个TypeScript模块。当需要让一个模块在其他模块中可见时,我们`export`它。
|
2016-03-16 12:01:33 -04:00
|
|
|
|
|
|
|
|
|
+makeExample('cb-ts-to-js/ts/app/hero.component.ts', 'appexport')(format="." )
|
|
|
|
|
|
|
|
|
|
:marked
|
|
|
|
|
In other modules we can then `import` things that have been exported
|
|
|
|
|
elsewhere.
|
2016-05-16 10:15:34 -04:00
|
|
|
|
|
|
|
|
|
然后,我们就可以在模块`import`其它地方导出的东西。
|
2016-03-16 12:01:33 -04:00
|
|
|
|
|
|
|
|
|
+makeExample('cb-ts-to-js/ts/app/main.ts', 'appimport')(format="." )
|
|
|
|
|
|
|
|
|
|
td
|
|
|
|
|
:marked
|
|
|
|
|
### Sharing Application Code
|
|
|
|
|
|
2016-05-16 10:15:34 -04:00
|
|
|
|
### 共享应用程序代码
|
|
|
|
|
|
2016-03-16 12:01:33 -04:00
|
|
|
|
In an Angular 2 JavaScript application, we load each file to the page
|
|
|
|
|
using a `<script>` tag. Each file can make things available to other
|
|
|
|
|
files via the shared global `window` scope.
|
2016-05-16 10:15:34 -04:00
|
|
|
|
|
|
|
|
|
在Angular 2 JavaScript应用程序里,我们在页面里面通过`<script>`标签来加载每个文件。
|
|
|
|
|
每个文件都能通过把所有东西放到全局`window`来互相共享·
|
2016-03-16 12:01:33 -04:00
|
|
|
|
|
|
|
|
|
We often introduce an application namespace
|
|
|
|
|
object (such as `"app"`) onto `window` and attach everything we need
|
|
|
|
|
to share to that namespace object.
|
|
|
|
|
We also wrap our code in an
|
|
|
|
|
[Immediately Invoked Function Expression (IIFE)](https://en.wikipedia.org/wiki/Immediately-invoked_function_expression).
|
|
|
|
|
These practices together prevent our code from
|
|
|
|
|
polluting the global scope.
|
2016-05-16 10:15:34 -04:00
|
|
|
|
|
|
|
|
|
我们经常在`window`上附加一个应用程序命名空间对象(比如`"app"`),然后把所有需要共享的东西都附加到这个空间对象。
|
|
|
|
|
也可以把我们的代码包装到一个[立即调用函数表达式IIFE](https://en.wikipedia.org/wiki/Immediately-invoked_function_expression)。
|
|
|
|
|
使用这些实践可以防止我们的代码污染全局范围。
|
2016-03-16 12:01:33 -04:00
|
|
|
|
|
|
|
|
|
+makeExample('cb-ts-to-js/js/app/hero.component.js', 'appexport')(format="." )
|
|
|
|
|
|
|
|
|
|
:marked
|
|
|
|
|
We can then access anything from this shared namespace in
|
|
|
|
|
other files.
|
2016-05-16 10:15:34 -04:00
|
|
|
|
|
|
|
|
|
然后我们就可以从这个共享的命名空间来访问其他文件。
|
2016-03-16 12:01:33 -04:00
|
|
|
|
|
|
|
|
|
+makeExample('cb-ts-to-js/js/app/main.js', 'appimport')(format="." )
|
|
|
|
|
|
|
|
|
|
:marked
|
|
|
|
|
Note that the order of `<script>` tags on the page is significant.
|
|
|
|
|
We must load a file that defines a shared member before
|
|
|
|
|
a file that uses that member.
|
2016-05-16 10:15:34 -04:00
|
|
|
|
|
|
|
|
|
注意,页面上的`<script>`标签的顺序非常重要。我们必须要先加载定义共享成员的文件,
|
|
|
|
|
然后再加载使用该共享成员的文件。
|
2016-03-16 12:01:33 -04:00
|
|
|
|
|
|
|
|
|
.alert.is-helpful
|
|
|
|
|
:marked
|
|
|
|
|
Alternatively, we can use a module loader such as Webpack or
|
|
|
|
|
Browserify in an Angular 2 JavaScript project. In such a project, we would
|
|
|
|
|
use CommonJS modules and the `require` function to load Angular 2 framework code.
|
|
|
|
|
We would then use `module.exports` and `require` to export and import application
|
|
|
|
|
code.
|
2016-05-16 10:15:34 -04:00
|
|
|
|
|
|
|
|
|
另外,我们可以在一个Angular 2 JavaScript项目中,使用模块加载器(比如Webpack或者Browserify)。
|
|
|
|
|
在这样的项目中,我们使用CommonJS模块和`require`函数来加载Angular 2框架代码。
|
|
|
|
|
然后用`module.exports`和`require`来导出和导入应用程序代码。
|
2016-03-16 12:01:33 -04:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
a(id="class-metadata")
|
|
|
|
|
.l-main-section
|
|
|
|
|
:marked
|
|
|
|
|
## Classes and Class Metadata
|
|
|
|
|
|
2016-05-16 10:15:34 -04:00
|
|
|
|
## 类和类元数据
|
|
|
|
|
|
2016-03-16 12:01:33 -04:00
|
|
|
|
- var top="vertical-align:top"
|
|
|
|
|
table(width="100%")
|
|
|
|
|
col(width="50%")
|
|
|
|
|
col(width="50%")
|
|
|
|
|
tr
|
|
|
|
|
th TypeScript
|
|
|
|
|
th ES5 JavaScript
|
|
|
|
|
tr(style=top)
|
|
|
|
|
td
|
|
|
|
|
:marked
|
|
|
|
|
### Classes
|
2016-05-16 10:15:34 -04:00
|
|
|
|
|
|
|
|
|
### 类
|
2016-03-16 12:01:33 -04:00
|
|
|
|
|
|
|
|
|
We put most of our Angular 2 TypeScript code into TypeScript classes.
|
2016-05-16 10:15:34 -04:00
|
|
|
|
|
|
|
|
|
我们把绝大多数Angular 2 TypeScript代码放到TypeScript类中。
|
2016-03-16 12:01:33 -04:00
|
|
|
|
|
|
|
|
|
+makeExample('cb-ts-to-js/ts/app/hero.component.ts', 'class')(format="." )
|
|
|
|
|
|
|
|
|
|
td
|
|
|
|
|
:marked
|
|
|
|
|
### Constructors and Prototypes
|
|
|
|
|
|
2016-05-16 10:15:34 -04:00
|
|
|
|
### 构造函数和原型
|
|
|
|
|
|
2016-03-16 12:01:33 -04:00
|
|
|
|
ES5 JavaScript has no classes. We use the constructor
|
|
|
|
|
pattern instead which works with Angular 2 as well as classes do.
|
2016-05-16 10:15:34 -04:00
|
|
|
|
|
|
|
|
|
ES5 JavaScript不支持类。取而代之,我们使用构造模式(constructor pattern),和类一样,它可以跟Angular 2一起工作。
|
2016-03-16 12:01:33 -04:00
|
|
|
|
|
|
|
|
|
+makeExample('cb-ts-to-js/js/app/hero.component.js', 'constructorproto')(format="." )
|
|
|
|
|
|
|
|
|
|
tr(style=top)
|
|
|
|
|
td
|
|
|
|
|
:marked
|
|
|
|
|
### Metadata with Decorators
|
|
|
|
|
|
2016-05-16 10:15:34 -04:00
|
|
|
|
### 拥有装饰器的元数据
|
|
|
|
|
|
2016-03-16 12:01:33 -04:00
|
|
|
|
Most Angular 2 classes have one or more TypeScript *decorators*
|
|
|
|
|
attached to provide configuration and metadata. For example,
|
2016-05-16 10:15:34 -04:00
|
|
|
|
a component must have a [`@Component`](../api/core/Component-decorator.html) decorator.
|
|
|
|
|
|
2016-03-16 12:01:33 -04:00
|
|
|
|
|
|
|
|
|
+makeExample('cb-ts-to-js/ts/app/hero.component.ts', 'metadata')(format="." )
|
|
|
|
|
|
|
|
|
|
td
|
|
|
|
|
:marked
|
|
|
|
|
### Metadata with the Annotations Array
|
|
|
|
|
|
|
|
|
|
In JavaScript, we can attach an `annotations` array to a constructor
|
|
|
|
|
to provide metadata.
|
|
|
|
|
Each item in the array corresponds to a TypeScript decorator.
|
|
|
|
|
|
|
|
|
|
In the following example, we create a new instance of `Component` that corresponds
|
|
|
|
|
to the [`@Component`](../api/core/Component-decorator.html) TypeScript decorator.
|
|
|
|
|
|
|
|
|
|
+makeExample('cb-ts-to-js/js/app/hero.component.js', 'metadata')(format="." )
|
|
|
|
|
|
|
|
|
|
:marked
|
|
|
|
|
### Metadata with The Class Convenience API
|
|
|
|
|
|
|
|
|
|
The pattern of creating a constructor and decorating it with metadata
|
|
|
|
|
is so common that Angular provides an alternative convenience API for it.
|
|
|
|
|
This API lets us define everything in a single expression.
|
|
|
|
|
|
|
|
|
|
With this API we first call the `ng.core.Component` function,
|
|
|
|
|
followed by a chained `Class` method call. The argument to `Class`
|
|
|
|
|
is an object that defines the constructor and the instance methods
|
|
|
|
|
of the component:
|
|
|
|
|
|
|
|
|
|
+makeExample('cb-ts-to-js/js/app/hero-dsl.component.js', 'component')(format="." )
|
|
|
|
|
|
|
|
|
|
:marked
|
|
|
|
|
Similar APIs are also available for other decorators. You can define a
|
|
|
|
|
directive:
|
|
|
|
|
|
|
|
|
|
code-example.
|
|
|
|
|
var MyDirective = ng.core.Directive({
|
|
|
|
|
...
|
|
|
|
|
}).Class({
|
|
|
|
|
...
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
:marked
|
|
|
|
|
Or a pipe:
|
|
|
|
|
|
|
|
|
|
code-example.
|
|
|
|
|
var MyPipe = ng.core.Pipe({
|
|
|
|
|
name: 'myPipe'
|
|
|
|
|
}).Class({
|
|
|
|
|
...
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
tr(style=top)
|
|
|
|
|
td
|
|
|
|
|
:marked
|
|
|
|
|
### Interfaces
|
|
|
|
|
|
|
|
|
|
When defining classes that need to implement a certain method, it
|
|
|
|
|
is common to use TypeScript interfaces that enforce that the
|
|
|
|
|
method signature is correct. Component lifecycle methods like `ngOnInit`
|
|
|
|
|
are one example of this pattern. `ngOnInit` is defined in the `OnInit`
|
|
|
|
|
interface.
|
|
|
|
|
|
|
|
|
|
+makeExample('cb-ts-to-js/ts/app/hero-lifecycle.component.ts')(format="." )
|
|
|
|
|
|
|
|
|
|
td
|
|
|
|
|
:marked
|
|
|
|
|
### Implementing Methods without Interfaces
|
|
|
|
|
|
|
|
|
|
TypeScript interfaces are purely for developer convenience
|
|
|
|
|
and are not used by Angular 2 at runtime. This means that in JavaScript
|
|
|
|
|
code we don't need to substitute anything for interfaces. We can just
|
|
|
|
|
implement the methods.
|
|
|
|
|
|
|
|
|
|
+makeExample('cb-ts-to-js/js/app/hero-lifecycle.component.js')(format="." )
|
|
|
|
|
|
|
|
|
|
a(id="property-metadata")
|
|
|
|
|
.l-main-section
|
|
|
|
|
:marked
|
|
|
|
|
## Input and Output Metadata
|
|
|
|
|
|
|
|
|
|
- var top="vertical-align:top"
|
|
|
|
|
table(width="100%")
|
|
|
|
|
col(width="50%")
|
|
|
|
|
col(width="50%")
|
|
|
|
|
tr
|
|
|
|
|
th TypeScript
|
|
|
|
|
th ES5 JavaScript
|
|
|
|
|
tr(style=top)
|
|
|
|
|
td
|
|
|
|
|
:marked
|
|
|
|
|
### Input and Output Decorators
|
|
|
|
|
|
|
|
|
|
In TypeScript, property decorators are often used to provide additional metadata
|
|
|
|
|
for components and directives.
|
|
|
|
|
|
|
|
|
|
For [inputs and outputs](../guide/template-syntax.html#inputs-outputs),
|
|
|
|
|
we use [`@Input`](../api/core/Input-var.html)
|
|
|
|
|
and [`@Output`](../api/core/Output-var.html) property decorators.
|
|
|
|
|
They may optionally specify input and output binding names if we want them to be
|
|
|
|
|
different from the class property names.
|
|
|
|
|
|
|
|
|
|
+makeExample('cb-ts-to-js/ts/app/hero-io.component.ts')(format="." )
|
|
|
|
|
|
|
|
|
|
.alert.is-helpful
|
|
|
|
|
:marked
|
|
|
|
|
In TypeScript we can also use the `inputs` and `outputs` array metadata
|
|
|
|
|
instead of the `@Input` and `@Output` property decorators.
|
|
|
|
|
td
|
|
|
|
|
:marked
|
|
|
|
|
### Inputs and Outputs in Component Metadata
|
|
|
|
|
|
|
|
|
|
There is no equivalent of a property decorator in ES5 JavaScript. Instead,
|
|
|
|
|
we add comparable information to the `Component` (or `Directive`) metadata.
|
|
|
|
|
|
|
|
|
|
In this example, we add `inputs` and `outputs` array attributes
|
|
|
|
|
containing the input and output property names.
|
|
|
|
|
If we need a binding name that is different from the
|
|
|
|
|
property itself, we use the `propertyName: bindingName` syntax.
|
|
|
|
|
|
|
|
|
|
+makeExample('cb-ts-to-js/js/app/hero-io.component.js')(format="." )
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
.l-main-section
|
|
|
|
|
:marked
|
|
|
|
|
## Dependency Injection
|
|
|
|
|
|
|
|
|
|
- var top="vertical-align:top"
|
|
|
|
|
table(width="100%")
|
|
|
|
|
col(width="50%")
|
|
|
|
|
col(width="50%")
|
|
|
|
|
tr
|
|
|
|
|
th TypeScript
|
|
|
|
|
th ES5 JavaScript
|
|
|
|
|
tr(style=top)
|
|
|
|
|
td
|
|
|
|
|
:marked
|
|
|
|
|
### Injection by Type
|
|
|
|
|
|
|
|
|
|
Angular 2 can often use TypeScript type information to
|
|
|
|
|
determine what needs to be injected.
|
|
|
|
|
|
|
|
|
|
+makeExample('cb-ts-to-js/ts/app/hero-di.component.ts')(format="." )
|
|
|
|
|
|
|
|
|
|
td
|
|
|
|
|
:marked
|
|
|
|
|
### Injection with Parameter Tokens
|
|
|
|
|
|
|
|
|
|
Since no type information is available in ES5 JavaScript,
|
|
|
|
|
we must identify "injectables" in some other way.
|
|
|
|
|
|
|
|
|
|
We attach a `parameters` array to the constructor function.
|
|
|
|
|
Each array item is the dependency injection token that identifies the thing to be injected.
|
|
|
|
|
Often the token is the constructor function for the class-like dependency.
|
|
|
|
|
|
|
|
|
|
+makeExample('cb-ts-to-js/js/app/hero-di.component.js')(format="." )
|
|
|
|
|
|
|
|
|
|
:marked
|
|
|
|
|
When using the class convenience API, we can also supply the parameter
|
|
|
|
|
tokens by wrapping the constructor in an array.
|
|
|
|
|
|
|
|
|
|
+makeExample('cb-ts-to-js/js/app/hero-di-inline.component.js')(format="." )
|
|
|
|
|
|
|
|
|
|
tr(style=top)
|
|
|
|
|
td
|
|
|
|
|
:marked
|
|
|
|
|
### Injection with the @Inject decorator
|
|
|
|
|
|
|
|
|
|
When the thing being injected doesn't correspond directly to a type,
|
|
|
|
|
we use the `@Inject()` decorator to supply the injection token.
|
|
|
|
|
|
|
|
|
|
In this example, we're injecting a string identified by the "heroName" token.
|
|
|
|
|
|
|
|
|
|
+makeExample('cb-ts-to-js/ts/app/hero-di-inject.component.ts')(format="." )
|
|
|
|
|
|
|
|
|
|
td
|
|
|
|
|
:marked
|
|
|
|
|
### Injection with plain string tokens
|
|
|
|
|
|
|
|
|
|
In JavaScript we add the token string to the injection parameters array.
|
|
|
|
|
|
|
|
|
|
+makeExample('cb-ts-to-js/js/app/hero-di-inject.component.js','parameters')(format="." )
|
|
|
|
|
|
|
|
|
|
:marked
|
|
|
|
|
Alternatively, we can create a token with the `Inject` method and
|
|
|
|
|
add that to the constructor array in the annotations like this:
|
|
|
|
|
|
|
|
|
|
+makeExample('cb-ts-to-js/js/app/hero-di-inject.component.js','ctor')(format="." )
|
|
|
|
|
|
|
|
|
|
tr(style=top)
|
|
|
|
|
td
|
|
|
|
|
:marked
|
|
|
|
|
### Additional Injection Decorators
|
|
|
|
|
|
|
|
|
|
We can attach additional decorators to constructor parameters
|
|
|
|
|
to qualify the injection behavior. We can mark
|
|
|
|
|
optional dependencies with the [`@Optional`](../api/core/Optional-var.html),
|
|
|
|
|
inject host element attributes with [`@Attribute`](../api/core/Attribute-var.html),
|
|
|
|
|
inject content child queries with [`@Query`](../api/core/Query-var.html)
|
|
|
|
|
and inject view child queries with [`@ViewQuery`](../api/core/ViewQuery-var.html)).
|
|
|
|
|
|
|
|
|
|
+makeExample('cb-ts-to-js/ts/app/hero-di-inject-additional.component.ts')(format="." )
|
|
|
|
|
|
|
|
|
|
td
|
|
|
|
|
:marked
|
|
|
|
|
### Additional Injection Metadata with Nested Arrays
|
|
|
|
|
|
|
|
|
|
To achieve the same effect in JavaScript, use the constructor array notation
|
|
|
|
|
in which the injection information precedes the constructor function itself.
|
|
|
|
|
|
|
|
|
|
Use the injection support functions `Attribute`, `Host`, `Optional`, `Self`, `SkipSelf`,
|
|
|
|
|
`Query` and `ViewQuery` to qualify dependency injection behavior.
|
|
|
|
|
|
|
|
|
|
Use a nested array to combine injection functions.
|
|
|
|
|
|
|
|
|
|
+makeExample('cb-ts-to-js/js/app/hero-di-inject-additional.component.js')(format="." )
|
|
|
|
|
|
|
|
|
|
:marked
|
|
|
|
|
We can apply other additional parameter decorators such as
|
|
|
|
|
[`@Host`](../api/core/Host-var.html) and
|
|
|
|
|
[`@SkipSelf`](../api/core/SkipSelf-var.html) in the same way -
|
|
|
|
|
by adding `new ng.core.Host()` or `ng.core.SkipSelf()` in the
|
|
|
|
|
parameters array.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
a(id="other-property-metadata")
|
|
|
|
|
.l-main-section
|
|
|
|
|
:marked
|
|
|
|
|
## Host and Query Metadata
|
|
|
|
|
|
|
|
|
|
- var top="vertical-align:top"
|
|
|
|
|
table(width="100%")
|
|
|
|
|
col(width="50%")
|
|
|
|
|
col(width="50%")
|
|
|
|
|
tr
|
|
|
|
|
th TypeScript
|
|
|
|
|
th ES5 JavaScript
|
|
|
|
|
tr(style=top)
|
|
|
|
|
|
|
|
|
|
td
|
|
|
|
|
:marked
|
|
|
|
|
### Host Decorators
|
|
|
|
|
|
|
|
|
|
We can use host property decorators to bind a host element to a component or directive.
|
|
|
|
|
The [`@HostBinding`](../api/core/HostBinding-var.html) decorator
|
|
|
|
|
binds host element properties to component data properties.
|
|
|
|
|
The [`@HostListener`](../api/core/HostListener-var.html) decorator bimds
|
|
|
|
|
host element events to component event handlers.
|
|
|
|
|
|
|
|
|
|
+makeExample('cb-ts-to-js/ts/app/heroes-bindings.component.ts')(format="." )
|
|
|
|
|
|
|
|
|
|
.alert.is-helpful
|
|
|
|
|
:marked
|
|
|
|
|
In TypeScript we can also use `host` metadata
|
|
|
|
|
instead of the `@HostBinding` and `@HostListener` property decorators.
|
|
|
|
|
td
|
|
|
|
|
:marked
|
|
|
|
|
### Host Metadata
|
|
|
|
|
|
|
|
|
|
We add a `host` attribute to the component metadata to achieve the
|
|
|
|
|
same effect as `@HostBinding` and `@HostListener`.
|
|
|
|
|
|
|
|
|
|
The `host` value is an object whose properties are host property and listener bindings:
|
|
|
|
|
|
|
|
|
|
* Each key follows regular Angular 2 binding syntax: `[property]` for host bindings
|
|
|
|
|
or `(event)` for host listeners.
|
|
|
|
|
* Each value identifies the corresponding component property or method.
|
|
|
|
|
|
|
|
|
|
+makeExample('cb-ts-to-js/js/app/heroes-bindings.component.js')(format="." )
|
|
|
|
|
|
|
|
|
|
tr(style=top)
|
|
|
|
|
td
|
|
|
|
|
:marked
|
|
|
|
|
### Query Decorators
|
|
|
|
|
|
|
|
|
|
There are several property decorators for querying the descendants of
|
|
|
|
|
a component or directive.
|
|
|
|
|
|
|
|
|
|
The [`@ViewChild`](../api/core/ViewChild-var.html) and
|
|
|
|
|
[`@ViewChildren`](../api/core/ViewChildren-var.html) property decorators
|
|
|
|
|
allow a component to query instances of other components that are used in
|
|
|
|
|
its view.
|
|
|
|
|
|
|
|
|
|
+makeExample('cb-ts-to-js/ts/app/heroes-queries.component.ts', 'view')(format="." )
|
|
|
|
|
|
|
|
|
|
:marked
|
|
|
|
|
The [`@ContentChild`](../api/core/ContentChild-var.html) and
|
|
|
|
|
[`@ContentChildren`](../api/core/ContentChildren-var.html) property decorators
|
|
|
|
|
allow a component to query instances of other components that have been projected
|
|
|
|
|
into its view from elsewhere.
|
|
|
|
|
|
|
|
|
|
+makeExample('cb-ts-to-js/ts/app/heroes-queries.component.ts', 'content')(format="." )
|
|
|
|
|
|
|
|
|
|
.alert.is-helpful
|
|
|
|
|
:marked
|
|
|
|
|
In TypeScript we can also use the `queries` metadata
|
|
|
|
|
instead of the `@ViewChild` and `@ContentChild` property decorators.
|
|
|
|
|
td
|
|
|
|
|
:marked
|
|
|
|
|
### Query Metadata
|
|
|
|
|
|
|
|
|
|
We access a component's view children by adding a `queries` attribute to
|
|
|
|
|
the component metadata. It should be an object where:
|
|
|
|
|
|
|
|
|
|
* Each key is the name of a component property that will hold the view children
|
|
|
|
|
* Each value is an instance of either `ViewChild` or `ViewChildren`.
|
|
|
|
|
|
|
|
|
|
+makeExample('cb-ts-to-js/js/app/heroes-queries.component.js', 'view')(format="." )
|
|
|
|
|
|
|
|
|
|
:marked
|
|
|
|
|
We add *content* child queries to the same `queries` attribute
|
|
|
|
|
in the same manner, using instances of `ContentChild` or `ContentChildren`:
|
|
|
|
|
|
|
|
|
|
+makeExample('cb-ts-to-js/js/app/heroes-queries.component.js', 'content')(format="." )
|