42 KiB
TypeScript to JavaScript
从 TypeScript 到 JavaScript
Introduction
简介
Anything you can do with Angular in TypeScript, you can also do in JavaScript. Translating from one language to the other is mostly a matter of changing the way you organize your code and access Angular APIs.
在 Angular 中,TypeScript 可以做的任何事,也可以用 JavaScript 实现。 将一种语言翻译成另一种语言,主要是改变了组织代码和访问 Angular API 的方式。
TypeScript is a popular language option for Angular development. Most code examples on the Internet as well as on this site are written in TypeScript. This cookbook contains recipes for translating TypeScript code examples to ES6 and to ES5 so that JavaScript developers can read and write Angular apps in their preferred dialect.
TypeScript
在 Angular 开发中比较流行。
互联网上和本网站中的大多数范例都是用 TypeScript
写的。
这本烹饪宝典会教你如何把 TypeScript
代码的例子翻译成 ES6
和 ES5
以便 JavaScript 的开发者可以用自己喜欢的语言来写 Angular 应用。
Run and compare the live TypeScript and JavaScript code shown in this cookbook.
运行并比较本章显示的在线例子的 TypeScript 版和 JavaScript 版。
TypeScript to ES6 to ES5
从_TypeScript_ 到 ES6 到 ES5
TypeScript is a typed superset of ES6 JavaScript. 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.
TypeScript 是 ES6 JavaScript 类型化的超集。ES6 JavaScript 是 ES5 JavaScript 的超集。ES5 是可以在所有现代浏览器中运行的 JavaScript。
The downgrade progression is as follows:
降级的过程是
-
TypeScript to ES6-with-decorators.
TypeScript 降级到 带装饰器的 ES6。
-
ES6-with-decorators to ES6-without-decorators ("plain ES6").
带装饰器的 ES6 降级到 没有装饰器的 ES6 (“普通 ES6”)。
-
ES6-without-decorators to ES5.
没有装饰器的 ES6 降级到 ES5。
When translating from TypeScript to ES6-with-decorators, remove
class property access modifiers
such as public
and private
.
Remove most of the
type declarations,
such as :string
and :boolean
but keep the constructor parameter types, which are used for dependency injection.
TypeScript 翻译到 带装饰器的 ES6 时,移除了类属性访问修饰符,如public
和private
。
移除了大部分的类型声明,如:string
和:boolean
。
但保留了用于依赖注入的构造函数参数类型。
From ES6-with-decorators to plain ES6, remove all
decorators
and the remaining types.
You must declare properties in the class constructor (this.title = '...'
) rather than in the body of the class.
带装饰器的 ES6 翻译到_普通 ES6_ 时,移除了所有的装饰器和剩下的类型。
必须在构造函数中声明属性(this.title = '...'
),而不是在类的代码体中。
Finally, from plain ES6 to ES5, the main missing features are import
statements and class
declarations.
最后,普通 ES6 翻译成 ES5,缺少的主要特性是import
和class
声明。
For plain ES6 transpilation you can start with a setup similar to the
TypeScript quickstart and adjust the application code accordingly.
Transpile with Babel using the es2015
preset.
To use decorators and annotations with Babel, install the
angular2
preset as well.
对_普通 ES6_ 的翻译,可以从类似 TypeScript 快速开始的设置开始,
调整相应代码。然后用 Babel 进行转译,使用es2015
预设值。
要在 Babel 中使用装饰器和注释,还需安装angular2
预设值。
{@a modularity}
Importing and Exporting
导入和导出
Importing Angular Code
导入 Angular 代码
In both TypeScript and ES6, you import Angular classes, functions, and other members with ES6 import
statements.
在 TypeScript 和 ES6 中,可以使用 ES6 import
语句导入 Angular 类、函数和其它成员。
In ES5, you access the Angular entities of the the Angular packages
through the global ng
object.
Anything you can import from @angular
is a nested member of this ng
object:
在 ES5 中,通过全局ng
对象访问 Angular 包中的 Angular 实体。
凡是可以从@angular
导入的,都是该ng
对象的嵌套成员。
Exporting application code
导出应用代码
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.
TypeScript 或 ES6 Angular 应用中每个文件都构成一个 ES6 模块。
当想要让某个东西对其它模块可用时,就export
它。
ES5 lacks native support for modules.
In an Angular ES5 application, you load each file manually by adding a <script>
tag to index.html
.
ES5 不支持模块。在 Angular ES5 应用中,需要在index.html
中添加<script>
标签,手工加载每个文件。
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.
<script>
标签的顺序通常很重要。
必须在引用实体的文件之前,加载定义该公共 JavaScript 实体的文件。
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
.
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
which leads to "exports" along the lines of app.heroQueries.HeroComponent
.
ES5 中,最佳实践是,创建某种形式的模块化,避免污染全局作用域。
添加一个应用命名空间对象(如app
)到全局的document
。
接着,每个代码文件都通过附加到该命名空间来“导出”公共实体,例如,app.HeroComponent
。
可以把一个大型应用中分解成多个子命名空间,可以象这样进行“导出”,app.heroQueries.HeroComponent
Every ES5 file should wrap code in an Immediately Invoked Function Expression (IIFE) to limit unintentional leaking of private symbols into the global scope.
每个 ES5 文件都应包裹在立即调用函数表达式 (IIFE) 中, 防止把私有符号无意地泄漏到全局作用域。
Here is a HeroComponent
as it might be defined and "exported" in each of the four language variants.
下面是HeroComponent
定义和“导出”的四种不同语言变种。
Importing application Code
导入应用代码
In TypeScript and ES6 apps, you import
things that have been exported from other modules.
在 TypeScript 和 ES6 应用中,可以导入 (import
) 其它模块已导出的东西。
In ES5 you use the shared namespace object to access "exported" entities from other files.
在 ES5 中,使用共享的命名空间对象访问其它文件“导出”的实体。
Alternatively, you can use a module loader such as Webpack or
Browserify in an Angular JavaScript project. In such a project, you would
use CommonJS modules and the require
function to load Angular framework code.
Then use module.exports
and require
to export and import application code.
还可以在 Angular JavaScript 项目中使用模块加载器,如 Webpack 或 Browserify。
在这样的项目中,使用 CommonJS 模块和require
函数来加载 Angular 框架代码。
用module.exports
和require
导入和导出应用代码。
{@a class-metadata}
Classes and Class Metadata
类和类的元数据
Classes
类
Most Angular TypeScript and ES6 code is written as classes.
大多数 Angular TypeScript 和 ES6 代码是写成了类。
Properties and method parameters of TypeScript classes may be marked with the access modifiers
private
, internal
, and public
.
Remove these modifiers when translating to JavaScript.
TypeScript 类的属性和方法参数可以用访问修饰符private
、internal
和public
标记。
当翻译成 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!
当翻译成 JavaScript 时,移除大多数类型声明(如,:string
和:boolean
)。
当翻译成_带装饰器的 ES6_ 时,不移除构造函数参数类型!
Look for types in TypeScript property declarations. In general it is better to initialize such properties with default values because many browser JavaScript engines can generate more performant code. When TypeScript code follows this same advice, it can infer the property types and there is nothing to remove during translation.
看一下 TypeScript 属性声明中的类型。通常,最好用缺省值初始化这些属性,因为许多浏览器的 JavaScript 引擎可生成更高性能的代码。当 TypeScript 代码遵循这一建议时,它可以推导出属性类型,翻译时就不需要移除任何内容。
In ES6-without-decorators, properties of classes must be assigned inside the constructor.
在_不带装饰器的 ES6_ 中,类的属性必须在构造函数中指定。
ES5 JavaScript has no classes. Use the constructor function pattern instead, adding methods to the prototype.
ES5 JavaScript 没有类。 使用构造函数模式,把方法添加到 prototype 中。
Metadata
元数据
When writing in TypeScript or ES6-with-decorators,
provide configuration and metadata by adorning a class with one or more decorators.
For example, you supply metadata to a component class by preceding its definition with a
@Component
decorator function whose
argument is an object literal with metadata properties.
当用 TypeScript 或 带装饰器的 ES6 编写代码时,使用一个或多个装饰器 (decorator) 来修饰类, 提供配置和元数据。
In plain ES6, you provide metadata by attaching an annotations
array to the class.
Each item in the array is a new instance of a metadata decorator created with a similar metadata object literal.
在_普通 ES6_ 中,通过向_类_附加一个annotations
数组来提供元数据。
In ES5, you also provide an annotations
array but you attach it to the constructor function rather than to a class.
在_ES5_中,也是提供一个annotations
数组,但把它附加到_构造函数_,而不是类。
See these variations side-by-side:
看一下这些变种:
External template file
外部模板文件
A large component template is often kept in a separate template file.
大的组件模板通常是放在独立的文件中。
The component, HeroTitleComponent
in this case, then references the template file in its metadata templateUrl
property:
接着,组件(这里是HeroTitleComponent
)在它的元数据templateUrl
属性中引用该模板文件:
Note that both the TypeScript and ES6 templateUrl
properties identify the location of the template file relative to the component module.
注意,TypeScript 和两个_ES6_的templateUrl
属性_相对于组件模块_来标识模板文件的位置。
{@a dsl}
ES5 DSL
ES5 领域专用语言
This ES5 pattern of creating a constructor and annotating it with metadata is so common that Angular provides a convenience API to make it a little more compact and locates the metadata above the constructor, as you would if you wrote in TypeScript or ES6-with-decorators.
创建构造函数并用元数据对它进行注释,是一个常见的 ES5 模式,Angular 提供了一套方便的 API,使代码更简洁, 并且元数据也刚好位于构造函数的上方,看起来就像 TypeScript 或 带装饰器的 ES6 写的代码。
This API (Application Programming Interface) is commonly known as the ES5 DSL (Domain Specific Language).
这个 API (Application Programming Interface,应用编程接口) 通常称作 ES5 DSL (Domain Specific Language,领域专用语言)。
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.
Then chain a call to the Class()
method which takes an object defining the class constructor and instance methods.
把ng.core.Component
函数调用的结果设置到应用命名空间属性,如app.HeroDslComponent
。
向ng.core.Component
传递与之前一样的元数据对象。
接着,在调用链上调用Class
函数,它接收一个对象,其中定义了类的构造函数和实例方法。
Here is an example of the HeroComponent
, re-written with the DSL,
next to the original ES5 version for comparison:
下例中的HeroComponent
,用 DSL 进行了重写,跟原来的 ES5 版本进行对比一下:
{@a name-constructor}
A named constructor displays clearly in the console log
if the component throws a runtime error.
An unnamed constructor displays as an anonymous function, for example, class0
,
which is impossible to find in the source code.
如果组件抛出运行时异常,命名的构造函数在控制台日志中显示得更清楚。
未命名的构造函数显示为匿名函数(如,class0
),不可能在源代码中找到它。
{@a getters-setters}
Properties with getters and setters
具有 getter 和 setter 的属性
TypeScript and ES6 support with getters and setters. Here's an example of a read-only TypeScript property with a getter that prepares a toggle-button label for the next clicked state:
TypeScript 和 ES6 支持 getter 和 setter。 下面是 TypeScript 只读属性的例子,它有一个 getter,为下一次点击状态准备切换按钮的标签:
This TypeScript "getter" property is transpiled to an ES5 defined property. The ES5 DSL does not support defined properties directly but you can still create them by extracting the "class" prototype and adding the defined property in raw JavaScript like this:
这个 TypeScript "getter" 属性会翻译成 ES5 已定义属性。 ES5 DSL 不直接支持_已定义属性_,你仍可提取“类”原型,象下面这样添加_已定义属性_:
{@a dsl-other}
DSL for other classes
用于其它类的 DSL
There are similar DSLs for other decorated classes.
You can define a directive with ng.core.Directive
:
其它被装饰的类也有类似的DSL,可以用ng.core.Directive
定义指令:
and a pipe with ng.core.Pipe
:
用ng.core.Pipe
添加一个管道:
{@a interfaces}
Interfaces
接口
A TypeScript interface helps ensure that a class implements the interface's members correctly.
Always try to use Angular interfaces where appropriate.
For example, the component class that implements the ngOnInit
lifecycle hook method
should implement the OnInit
interface.
_TypeScript_用于确保一个类正确地实现了接口成员。
在适当的地方,我们强烈推荐使用 Angular 接口。
例如,实现了ngOnInit
生命周期钩子方法的组件类应实现OnInit
接口。
TypeScript interfaces exist for developer convenience and are not used by Angular at runtime. 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.
TypeScript 接口只是为了方便开发人员,Angular 在运行时并不使用它。 它们在生成的 JavaScript中并不存在。 当从 TypeScript 翻译成 JavaScript 时,只保留了实现方法,而忽略接口。
{@a io-decorators}
Input and Output Metadata
输入和输出元数据
Input and Output Decorators
输入和输出装饰器
In TypeScript and ES6-with-decorators, you often add metadata to class properties with property decorators.
For example, you apply @Input
and @Output
property decorators
to public class properties that will be the target of data binding expressions in parent components.
在 TypeScript 和 带装饰器的 ES6 中,经常会用_属性装饰器_往类的_属性_上添加元数据。
例如,向公共类属性添加@Input
和@Output
属性装饰器 ,
会使这些属性成为父组件绑定表达式的目标。
There is no equivalent of a property decorator in ES5 or plain ES6.
Fortunately, every property decorator has an equivalent representation in a class decorator metadata property.
A TypeScript @Input
property decorator can be represented by an item in the Component
metadata's inputs
array.
在 ES5 或 普通 ES6 中,没有等价的属性装饰器。
幸运的是,每个属性装饰器在类的装饰器元数据属性中有等价的表示形式。
TypeScript 的@Input
属性装饰器可以表示为Component
元数据的inputs
数组中的一项。
You already know how to add Component
or Directive
class metadata in any JavaScript dialect so
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
combined in the metadata inputs
and outputs
arrays.
你已经知道如何用_任意的_ JavaScript 方言添加Component
或 Directive
元数据,
所以添加另一个属性也没什么新鲜的。
但要注意的是,用于每个类属性的那些_分离_的@Input
和@Output
属性装饰器,都合并到了inputs
和outputs
_数组_中。
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
to the component's notOkMsg
property.
上例中,其中一个面向公共的绑定名 (cancelMsg
),不同于相应的类属性名 (notOkMsg
)。
这样做没有问题,但必须把它告诉 Angular,这样 Angular 才能把cancelMsg
的外部绑定映射到组件的notOkMsg
属性。
In TypeScript and ES6-with-decorators, you specify the special binding name in the argument to the property decorator.
在 TypeScript 和 带装饰器的 ES6 中,在属性装饰器的参数中指定特定的绑定名。
In ES5 and plain ES6 code, convey this pairing with the propertyName: bindingName
syntax in the class metadata.
在 ES5 或 普通 ES6 中,用propertyName: bindingName
语法表示在类的元数据中。
{@a dependency-injection}
Dependency injection
依赖注入
Angular relies heavily on Dependency Injection to provide services to the objects it creates. 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.
Angular 严重依赖依赖注入来为它创建的对象提供服务。 当 Angular 创建一个新组件、指令、管道或其它服务时, 它把_注入器_提供的服务的实例传递给类的构造函数参数。
The developer must tell Angular what to inject into each parameter.
开发人员必须告诉 Angular 向每个参数中注入什么。
{@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 to the class associated with the service to inject.
在 TypeScript 和 带装饰器的 ES6 中,最简单和流行的技术是把构造函数参数的类型设置为待注入服务的类。
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. The ES6-with-decorators transpiler does essentially the same thing using the same parameter-typing syntax.
TypeScript 转译器把参数类型信息写进生成的 JavaScript。 Angular 在运行时读取该信息,并在适当的_注入器_中定位相应的服务。 带装饰器的 ES6 转译器本质上也使用同样的参数类型语法,做同样的工作。
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.
ES5 或 普通 ES6 缺少类型,必须向构造函数附加**parameters
**数组来标识“可注入对象”。
数组中的每一项指定一个服务的注入令牌。
As with TypeScript, the most popular token is a class,
or rather a constructor function that represents a class in ES5 and plain ES6.
The format of the parameters
array varies:
TypeScript 中,最常用的令牌是类,而_ES5_ 和 普通 ES6 使用_构造函数_表示一个类。
因此,parameters
数组会有所不同:
-
Plain ES6 — nest each constructor function in a sub-array.
普通 ES6 — 函数构造嵌套在一个子数组中。
-
ES5 — simply list the constructor functions.
ES5 — 简单列出构造函数。
When writing with ES5 DSL, set the Class.constructor
property to
an array whose first parameters are the injectable constructor functions and whose
last parameter is the class constructor itself.
This format should be familiar to AngularJS developers.
当用 ES5 DSL 时,把Class.constructor
属性设置为一个数组,它的前面的参数是
注入的服务,最后一个参数是类构造函数本身。
AngularJS 的开发人员对这种形式应该很熟悉。
Injection with the @Inject decorator
用 @Inject 装饰器注入
Sometimes the dependency injection token isn't a class or constructor function.
有时,依赖注入的令牌不是类或构造函数。
In TypeScript and ES6-with-decorators, you precede the class constructor parameter
by calling the @Inject()
decorator with the injection token.
In the following example, the token is the string 'heroName'
.
在 TypeScript 和 带装饰器的 ES6 中,可以在类的构造函数参数前调用@Inject()
装饰器来指定注入令牌。
在这个例子中,这个令牌是字符串'heroName'
The other JavaScript dialects add a parameters
array to the class constructor function.
Each item contains a new instance of Inject
:
其它 JavaScript 方言是通过向类的构造函数添加parameters
数组。
其中的每一项是Inject
的实例。
-
Plain ES6 — each item is a new instance of
Inject(token)
in a sub-array.普通 ES6 — 每一项是嵌套在一个子数组中的
Inject(token)
的实例。 -
ES5 — simply list the string tokens.
ES5 — 简单列出字符串令牌。
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.
当用 ES5 DSL 时,象前面那样把Class.constructor
属性设置为函数定义数组。
为每个参数创建一个ng.core.Inject(token)
。
Additional Injection Decorators
其它注入装饰器
You can qualify injection behavior with injection decorators from @angular/core
.
可以使用@angular/core
中的注入装饰器来限定注入行为。
In TypeScript and ES6-with-decorators, you precede the constructor parameters with injection qualifiers such as:
在 TypeScript 和 带装饰器的 ES6 中,可以将下列注入限定符加在构造函数参数前面:
-
@Optional
sets the parameter tonull
if the service is missing.@Optional
如果找不到服务,设置参数为null
-
@Attribute
to inject a host element attribute value.@Attribute
注入宿主元素属性值 -
@ContentChild
to inject a content child.@ContentChild
注入内容子组件 -
@ViewChild
to inject a view child.@ViewChild
注入视图子组件 -
@Host
to inject a service in this component or its host.@Host
注入本组件或它宿主中的服务 -
@SkipSelf
to inject a service provided in an ancestor of this component.@SkipSelf
注入本组件祖先中提供的服务
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.
在_ES5_ 或 普通 ES6 中,通过在parameters
数组中创建一个嵌套数组,创建等价的注入限定符实例。
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.
当用 ES5 DSL 时,象前面那样把Class.constructor
属性设置为函数定义数组。
用嵌套数组来定义参数完整的注入规格说明。
In the example above, there is no provider for the 'titlePrefix'
token.
Without @Optional()
, Angular would raise an error.
With @Optional()
, Angular sets the constructor parameter to null
and the component displays the title without a prefix.
上例中,'titlePrefix'
令牌没有提供商。
如果没有Optional
,Angular 将抛出错误。
加上Optional
,Angular 将构造函数参数设置为null
,
组件显示没有前缀的标题。
{@a host-binding}
Host Binding
宿主绑定
Angular supports bindings to properties and events of the host element, which is the element whose tag matches the component selector.
Angular 支持绑定到_宿主元素_的属性和事件, 宿主元素是那些标签匹配组件选择器的元素。
Host Decorators
宿主装饰器
In TypeScript and ES6-with-decorators, you can use host property decorators to bind a host
element to a component or directive.
The @HostBinding
decorator
binds host element properties to component data properties.
The @HostListener
decorator binds
host element events to component event handlers.
在 TypeScript 和 带装饰器的 ES6 中,可以使用宿主属性装饰器把宿主元素绑定到组件或指令。
@HostBinding
装饰器把宿主元素属性绑定到组件数据属性。
@HostListener
装饰器把宿主元素事件绑定到组件事件处理器。
In plain ES6 or ES5, add a host
attribute to the component metadata to achieve the
same effect as @HostBinding
and @HostListener
.
在_ES5_ 或 普通 ES6 中,向组件元数据添加host
属性可以获得同样的效果。
The host
value is an object whose properties are host property and listener bindings:
host
的值是一个对象,它的属性是宿主属性和监听器绑定:
-
Each key follows regular Angular binding syntax:
[property]
for host bindings or(event)
for host listeners.每个键遵循 Angular 绑定语法:
[property]
用于宿主绑定,(event)
用于宿主监听器。 -
Each value identifies the corresponding component property or method.
每个值标识相应的组件属性或方法。
Host Metadata
宿主元数据
Some developers prefer to specify host properties and listeners in the component metadata. They'd rather do it the way you must do it ES5 and plain ES6.
一些开发人员更喜欢在组件元数据中指定宿主属性和监听器。 它们宁愿采用这种方式,也是 ES5 或 普通 ES6 中必须采用的方式。
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.
These particular TypeScript and ES6 code snippets happen to be identical.
下面重新实现了HeroComponent
,它提醒我们,在 TypeScript 和 带装饰器的 ES6 中,
_任何属性元数据装饰器_都可以表示为组件或指令元数据。
{@a view-child-decorators}
View and Child Decorators
视图和子组件装饰器
Several property decorators query a component's nested view and content components.
有几个_属性_装饰器可用于查询组件的嵌套视图和内容组件。
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;
they are projected into an <ng-content>
slot in the component's template.
_内容_子组件与出现在组件元素标签_之间_的那些元素相关联,
它们被投影到组件模板的<ng-content>
中。
The @ViewChild
and
@ViewChildren
property decorators
allow a component to query instances of other components that are used in
its view.
@ViewChild
和
@ViewChildren
属性装饰器允许组件查询位于其视图中的其它组件的实例。
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.
在 ES5 和 ES6 中,通过向组件元数据添加queries
属性来访问组件的视图子组件。
queries
属性是一个映射表。
-
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
orViewChildren
.每个_值_是
ViewChild
或ViewChildren
的实例。
The @ContentChild
and
@ContentChildren
property decorators
allow a component to query instances of other components that have been projected
into its view from elsewhere.
@ContentChild
和
@ContentChildren
装饰器允许组件查询从其它地方投影到视图里的其它组件的实例。
They can be added in the same way as @ViewChild
and
@ViewChildren
.
添加它们的方式与@ViewChild
和
@ViewChildren
相同。
In TypeScript and ES6-with-decorators you can also use the queries
metadata
instead of the @ViewChild
and @ContentChild
property decorators.
在 TypeScript 和 带装饰器的 ES6 中,还可以使用queries
元数据代替
@ViewChild
和 @ContentChild
属性装饰器。
{@a aot}
AOT Compilation in TypeScript only
只用于 TypeScript 的预编译
Angular offers two modes of template compilation, JIT (just-in-time) and AOT (ahead-of-time). Currently the AOT compiler only works with TypeScript applications because, in part, it generates TypeScript files as an intermediate result. AOT is not an option for pure JavaScript applications at this time.
Angular 模板编译有两种方式:JiT (Just-in-Time,即时编译) 和 AoT (Ahead-of-Time,预编译)。 目前,预编译只能用于 TypeScript 应用,因为(部分原因)它生成的中间结果是 TypeScript 文件。 当前,预编译不能用于纯 JavaScript 应用。