13 KiB
Introduction to components
A component controls a patch of screen called a view. For example, individual components define and control each of the following views from the Tutorial:
-
The app root with the navigation links.
带有导航链接的应用根组件。
-
The list of heroes.
英雄列表。
-
The hero editor.
英雄编辑器。
You define a component's application logic—what it does to support the view—inside a class. The class interacts with the view through an API of properties and methods.
你在类中定义组件的应用逻辑,为视图提供支持。 组件通过一些由属性和方法组成的 API 与视图交互。
For example, the HeroListComponent
has a heroes
property that returns an array of heroes that it acquires from a service. HeroListComponent
also has a selectHero()
method that sets a selectedHero
property when the user clicks to choose a hero from that list.
Angular creates, updates, and destroys components as the user moves through the application. Your app can take action at each moment in this lifecycle through optional lifecycle hooks, like ngOnInit()
.
Component metadata
The @Component
decorator identifies the class immediately below it as a component class, and specifies its metadata. In the example code below, you can see that HeroListComponent
is just a class, with no special Angular notation or syntax at all. It's not a component until mark it as one with the @Component
decorator.
The metadata for a component tells Angular where to get the major building blocks it needs to create and present the component and its view. In particular, it associates a template with the component, either directly with inline code, or by reference. Together, the component and its template describe a view.
In addition to containing or pointing to the template, the @Component
metadata configures, for example, how the component can be referenced in HTML and what services it requires.
Here's an example of basic metadata for HeroListComponent
:
This example shows some of the most useful @Component
configuration options:
-
selector
: A CSS selector that tells Angular to create and insert an instance of this component wherever it finds the corresponding tag in template HTML. For example, if an app's HTML contains<app-hero-list></app-hero-list>
, then Angular inserts an instance of theHeroListComponent
view between those tags. -
templateUrl
: The module-relative address of this component's HTML template. Alternatively, you can provide the HTML template inline, as the value of thetemplate
property. This template defines the component's host view. -
providers
: An array of dependency injection providers for services that the component requires. In the example, this tells Angular that the component's constructor requires aHeroService
instance in order to get the list of heroes to display.
Templates and views
You define a component's view with its companion template. A template is a form of HTML that tells Angular how to render the component.
Views are typically arranged hierarchically, allowing you to modify or show and hide entire UI sections or pages as a unit. The template immediately associated with a component defines that component's host view. The component can also define a view hierarchy, which contains embedded views, hosted by other components.
A view hierarchy can include views from components in the same NgModule, but it also can (and often does) include views from components that are defined in different NgModules.
Template syntax
A template looks like regular HTML, except that it also contains Angular template syntax, which alters the HTML based on your app's logic and the state of app and DOM data. Your template can use data binding to coordinate the app and DOM data, pipes to transform data before it is displayed, and directives to apply app logic to what gets displayed.
For example, here is a template for the Tutorial's HeroListComponent
:
This template uses typical HTML elements like <h2>
and <p>
, and also includes Angular template-syntax elements, *ngFor
, {{hero.name}}
, (click)
, [hero]
, and <app-hero-detail>
. The template-syntax elements tell Angular how to render the HTML to the screen, using program logic and data.
-
The
*ngFor
directive tells Angular to iterate over a list. -
The
{{hero.name}}
,(click)
, and[hero]
bind program data to and from the DOM, responding to user input. See more about data binding below. -
The
<app-hero-detail>
tag in the example is an element that represents a new component,HeroDetailComponent
. TheHeroDetailComponent
(code not shown) is a child component of theHeroListComponent
that defines the Hero-detail view. Notice how custom components like this mix seamlessly with native HTML in the same layouts.
Data binding
Without a framework, you would be responsible for pushing data values into the HTML controls and turning user responses into actions and value updates. Writing such push/pull logic by hand is tedious, error-prone, and a nightmare to read, as any experienced jQuery programmer can attest.
Angular supports two-way data binding, a mechanism for coordinating parts of a template with parts of a component. Add binding markup to the template HTML to tell Angular how to connect both sides.
The following diagram shows the four forms of data binding markup. Each form has a direction—to the DOM, from the DOM, or in both directions.
This example from the HeroListComponent
template uses three of these forms:
-
The
{{hero.name}}
interpolation displays the component'shero.name
property value within the<li>
element.{{hero.name}}
插值表达式在<li>
标签中显示组件的hero.name
属性的值。 -
The
[hero]
property binding passes the value ofselectedHero
from the parentHeroListComponent
to thehero
property of the childHeroDetailComponent
.[hero]
属性绑定把父组件HeroListComponent
的selectedHero
的值传到子组件HeroDetailComponent
的hero
属性中。 -
The
(click)
event binding calls the component'sselectHero
method when the user clicks a hero's name.
Two-way data binding is an important fourth form that combines property and event binding in a single notation. Here's an example from the HeroDetailComponent
template that uses two-way data binding with the ngModel
directive:
In two-way binding, a data property value flows to the input box from the component as with property binding. The user's changes also flow back to the component, resetting the property to the latest value, as with event binding.
在双向绑定中,数据属性值通过属性绑定从组件流到输入框。用户的修改通过事件绑定流回组件,把属性值设置为最新的值。
Angular processes all data bindings once per JavaScript event cycle, from the root of the application component tree through all child components.
Angular 在每个 JavaScript 事件循环中处理所有的数据绑定,它会从组件树的根部开始,递归处理全部子组件。
Data binding plays an important role in communication between a template and its component, and is also important for communication between parent and child components.
Pipes
管道
Angular pipes let you declare display-value transformations in your template HTML. A class with the @Pipe
decorator defines a function that transforms input values to output values for display in a view.
Angular defines various pipes, such as the date pipe and currency pipe; for a complete list, see the Pipes API list. You can also define new pipes.
To specify a value transformation in an HTML template, use the pipe operator (|):
{{interpolated_value | pipe_name}}
You can chain pipes, sending the output of one pipe function to be transformed by another pipe function. A pipe can also take arguments that control how it performs its transformation. For example, you can pass the desired format to the date
pipe:
<!-- Default format: output 'Jun 15, 2015'-->
<p>Today is {{today | date}}</p>
<!-- fullDate format: output 'Monday, June 15, 2015'-->
<p>The date is {{today | date:'fullDate'}}</p>
<!-- shortTime format: output '9:43 AM'-->
<p>The time is {{today | date:'shortTime'}}</p>
Directives
Angular templates are dynamic. When Angular renders them, it transforms the DOM according to the instructions given by directives. A directive is a class with a @Directive
decorator.
A component is technically a directive - but components are so distinctive and central to Angular applications that Angular defines the @Component
decorator, which extends the @Directive
decorator with template-oriented features.
There are two kinds of directives besides components: structural and attribute directives. Just as for components, the metadata for a directive associates the class with a selector
that you use to insert it into HTML. In templates, directives typically appear within an element tag as attributes, either by name or as the target of an assignment or a binding.
Structural directives
Structural directives alter layout by adding, removing, and replacing elements in DOM. The example template uses two built-in structural directives to add application logic to how the view is rendered:
-
*ngFor
is an iterative; it tells Angular to stamp out one<li>
per hero in theheroes
list. -
*ngIf
is a conditional; it includes theHeroDetail
component only if a selected hero exists.
Attribute directives
Attribute directives alter the appearance or behavior of an existing element. In templates they look like regular HTML attributes, hence the name.
The ngModel
directive, which implements two-way data binding, is an example of an attribute directive. ngModel
modifies the behavior of an existing element (typically an <input>
) by setting its display value property and responding to change events.
ngModel
指令就是属性型指令的一个例子,它实现了双向数据绑定。
ngModel
修改现有元素(一般是 <input>
)的行为:设置其显示属性值,并响应 change 事件。
Angular has more pre-defined directives that either alter the layout structure (for example, ngSwitch) or modify aspects of DOM elements and components (for example, ngStyle and ngClass).
You can also write your own directives. Components such as HeroListComponent
are one kind of custom directive. You can also create custom structural and attribute directives.