parent
72efc8f055
commit
bfc5c70349
|
@ -5,24 +5,29 @@ a(id="top")
|
|||
This chapter provides a quick reference guide to some of the common Angular 1
|
||||
syntax and its equivalent in Angular 2.
|
||||
|
||||
在Angular 1和Anuglar 2之间,有很多不同的概念和语法。
|
||||
本章提供了一个快速的参考指南,指出一些常用的Angular 1语法及其在Angular 2中的等价物。
|
||||
|
||||
:marked
|
||||
**See the Angular 2 syntax in this [live example](/resources/live-examples/cb-a1-a2-quick-reference/ts/plnkr.html)**.
|
||||
|
||||
**可到[在线范例](/resources/live-examples/cb-a1-a2-quick-reference/ts/plnkr.html)中查看Angular 2语法**。
|
||||
|
||||
## Contents
|
||||
This chapter covers
|
||||
* [Template Basics](#template-basics) - binding and local variables
|
||||
|
||||
|
||||
* [Template Directives](#template-directives) - built-in directives `ngIf` and `ngClass`
|
||||
|
||||
|
||||
* [Filters/Pipes](#filters-pipes) - built-in *filters*, known as *pipes* in Angular 2
|
||||
|
||||
* [Controllers/Components](#controllers-components) - *controllers* are *components* in Angular 2.
|
||||
|
||||
* [Controllers/Components](#controllers-components) - *controllers* are *components* in Angular 2.
|
||||
Also covers modules.
|
||||
|
||||
|
||||
* [Style Sheets](#style-sheets) - more options for CSS in Angular 2.
|
||||
|
||||
|
||||
* [String date pipe](#string-dates) - a tip for displaying string date values.
|
||||
|
||||
|
||||
.l-main-section
|
||||
:marked
|
||||
## Template Basics
|
||||
|
@ -33,7 +38,7 @@ a(id="top")
|
|||
- var top="vertical-align:top"
|
||||
table(width="100%")
|
||||
col(width="50%")
|
||||
col(width="50%")
|
||||
col(width="50%")
|
||||
tr
|
||||
th Angular 1
|
||||
th Angular 2
|
||||
|
@ -47,7 +52,7 @@ table(width="100%")
|
|||
In Angular 1, an expression in curly braces denotes one-way binding.
|
||||
This binds the value of the element to a property in the controller
|
||||
associated with this template.
|
||||
|
||||
|
||||
When using the `controller as` syntax,
|
||||
the binding is prefixed with the controller alias (`vm`) because we
|
||||
have to be specific about the source of the binding.
|
||||
|
@ -60,7 +65,7 @@ table(width="100%")
|
|||
This binds the value of the element to a property of the component.
|
||||
The context of the binding is implied and is always the
|
||||
associated component, so it needs no reference variable.
|
||||
|
||||
|
||||
For more information see [Template Syntax](../guide/template-syntax.html#interpolation).
|
||||
tr(style=top)
|
||||
td
|
||||
|
@ -70,7 +75,7 @@ table(width="100%")
|
|||
<td>{{movie.title | uppercase}}</td>
|
||||
:marked
|
||||
To filter output in our templates in Angular 1, we use the pipe character (|) and one or more filters.
|
||||
|
||||
|
||||
In this example, we filter the `title` property to uppercase.
|
||||
td
|
||||
:marked
|
||||
|
@ -80,7 +85,7 @@ table(width="100%")
|
|||
In Angular 2, we use similar syntax with the pipe (|) character to filter output, but now we call them **pipes**.
|
||||
Many (but not all) of the built-in filters from Angular 1 are
|
||||
built-in pipes in Angular 2.
|
||||
|
||||
|
||||
See the heading [Filters / Pipes](#Pipes) below for more information.
|
||||
tr(style=top)
|
||||
td
|
||||
|
@ -98,21 +103,21 @@ table(width="100%")
|
|||
+makeExample('cb-a1-a2-quick-reference/ts/app/app.component.html', 'local')(format="." )
|
||||
:marked
|
||||
In Angular 2, we have true template input variables that are explicitly defined using the `let` keyword.
|
||||
|
||||
|
||||
For more information see [ngFor micro-syntax](../guide/template-syntax.html#ngForMicrosyntax).
|
||||
:marked
|
||||
[Back to top](#top)
|
||||
|
||||
|
||||
.l-main-section
|
||||
:marked
|
||||
## Template Directives
|
||||
Angular 1 provides over seventy built-in directives for use in our templates.
|
||||
Many of them are no longer needed in Angular 2 because of its more capable and expressive binding system.
|
||||
Angular 1 provides over seventy built-in directives for use in our templates.
|
||||
Many of them are no longer needed in Angular 2 because of its more capable and expressive binding system.
|
||||
The following are some of the key Angular 1 built-in directives and the equivalent feature in Angular 2.
|
||||
|
||||
table(width="100%")
|
||||
col(width="50%")
|
||||
col(width="50%")
|
||||
col(width="50%")
|
||||
tr
|
||||
th Angular 1
|
||||
th Angular 2
|
||||
|
@ -121,10 +126,10 @@ table(width="100%")
|
|||
:marked
|
||||
### ng-app
|
||||
code-example.
|
||||
<body ng-app="movieHunter">
|
||||
<body ng-app="movieHunter">
|
||||
:marked
|
||||
The application startup process is called **bootstrapping**.
|
||||
|
||||
|
||||
Although we can bootstrap an Angular 1 app in code,
|
||||
many applications bootstrap declaratively with the `ng-app` directive,
|
||||
giving it the name of the application's module (`movieHunter`).
|
||||
|
@ -136,7 +141,7 @@ table(width="100%")
|
|||
Angular 2 does not have a bootstrap directive.
|
||||
We always launch the app in code by explicitly calling a bootstrap function
|
||||
and passing it the name of the application's module (`AppComponent`).
|
||||
|
||||
|
||||
For more information see [Quick Start](../quickstart.html).
|
||||
tr(style=top)
|
||||
td
|
||||
|
@ -144,32 +149,32 @@ table(width="100%")
|
|||
### ng-class
|
||||
code-example(format="").
|
||||
<div ng-class="{active: isActive}">
|
||||
<div ng-class="{active: isActive,
|
||||
<div ng-class="{active: isActive,
|
||||
shazam: isImportant}">
|
||||
:marked
|
||||
In Angular 1, the `ng-class` directive includes/excludes CSS classes
|
||||
based on an expression. That expression is often a key-value control object with each
|
||||
key of the object defined as a CSS class name, and each value defined as a template expression
|
||||
that evaluates to a Boolean value.
|
||||
|
||||
|
||||
In the first example, the `active` class is applied to the element if `isActive` is true.
|
||||
|
||||
|
||||
We can specify multiple classes as shown in the second example.
|
||||
td
|
||||
:marked
|
||||
### ngClass
|
||||
+makeExample('cb-a1-a2-quick-reference/ts/app/app.component.html', 'ngClass')(format="." )
|
||||
:marked
|
||||
In Angular 2, the `ngClass` directive works similarly.
|
||||
It includes/excludes CSS classes based on an expression.
|
||||
|
||||
In Angular 2, the `ngClass` directive works similarly.
|
||||
It includes/excludes CSS classes based on an expression.
|
||||
|
||||
In the first example, the `active` class is applied to the element if `isActive` is true.
|
||||
|
||||
|
||||
We can specify multiple classes as shown in the second example.
|
||||
|
||||
Angular 2 also has **class binding**, which is a good way to add or remove a single class
|
||||
|
||||
Angular 2 also has **class binding**, which is a good way to add or remove a single class
|
||||
as shown in the third example.
|
||||
|
||||
|
||||
For more information see [Template Syntax](../guide/template-syntax.html#other-bindings).
|
||||
|
||||
tr(style=top)
|
||||
|
@ -181,9 +186,9 @@ table(width="100%")
|
|||
<button ng-click="vm.toggleImage($event)">
|
||||
:marked
|
||||
In Angular 1, the `ng-click` directive allows us to specify custom behavior when an element is clicked.
|
||||
|
||||
|
||||
In the first example, when the button is clicked, the `toggleImage()` method in the controller referenced by the `vm` `controller as` alias is executed.
|
||||
|
||||
|
||||
The second example demonstrates passing in the `$event` object, which provides details about the event
|
||||
to the controller.
|
||||
td
|
||||
|
@ -191,21 +196,21 @@ table(width="100%")
|
|||
### bind to the `click` event
|
||||
+makeExample('cb-a1-a2-quick-reference/ts/app/app.component.html', 'event-binding')(format="." )
|
||||
:marked
|
||||
The Angular 1 event-based directives do not exist in Angular 2.
|
||||
The Angular 1 event-based directives do not exist in Angular 2.
|
||||
Rather, we define one-way binding from the template view to the component using **event binding**.
|
||||
|
||||
|
||||
For event binding, we define the name of the target event within parenthesis and
|
||||
specify a template statement in quotes to the right of the equals. Angular 2 then
|
||||
sets up an event handler for the target event. When the event is raised, the handler
|
||||
executes the template statement.
|
||||
|
||||
|
||||
In the first example, when the button is clicked, the `toggleImage()` method in the associated component is executed.
|
||||
|
||||
|
||||
The second example demonstrates passing in the `$event` object, which provides details about the event
|
||||
to the component.
|
||||
|
||||
|
||||
For a list of DOM events, see: https://developer.mozilla.org/en-US/docs/Web/Events.
|
||||
|
||||
|
||||
For more information see [Template Syntax](../guide/template-syntax.html#event-binding).
|
||||
|
||||
tr(style=top)
|
||||
|
@ -215,17 +220,17 @@ table(width="100%")
|
|||
code-example(format="").
|
||||
<div ng-controller="MovieListCtrl as vm">
|
||||
:marked
|
||||
In Angular 1, the `ng-controller` directive attaches a controller to the view.
|
||||
In Angular 1, the `ng-controller` directive attaches a controller to the view.
|
||||
Using the `ng-controller` (or defining the controller as part of the routing) ties the
|
||||
view to the controller code associated with that view.
|
||||
view to the controller code associated with that view.
|
||||
td
|
||||
:marked
|
||||
### Component decorator
|
||||
+makeExample('cb-a1-a2-quick-reference/ts/app/movie-list.component.ts', 'component')(format="." )
|
||||
:marked
|
||||
In Angular 2, the template no longer specifies its associated controller.
|
||||
In Angular 2, the template no longer specifies its associated controller.
|
||||
Rather, the component specifies its associated template as part of the component class decorator.
|
||||
|
||||
|
||||
For more information see [Architecture Overview](../guide/architecture.html#component).
|
||||
|
||||
tr(style=top)
|
||||
|
@ -262,9 +267,9 @@ table(width="100%")
|
|||
:marked
|
||||
In Angular 2, we use property binding; there is no built-in *href* directive.
|
||||
We place the element's `href` property in square brackets and set it to a quoted template expression.
|
||||
|
||||
|
||||
For more information on property binding see [Template Syntax](../guide/template-syntax.html#property-binding).
|
||||
|
||||
|
||||
In Angular 2, `href` is no longer used for routing. Routing uses `routerLink` as shown in the third example.
|
||||
+makeExample('cb-a1-a2-quick-reference/ts/app/app.component.html', 'router-link')(format="." )
|
||||
:marked
|
||||
|
@ -279,18 +284,18 @@ table(width="100%")
|
|||
:marked
|
||||
In Angular 1, the `ng-if` directive removes or recreates a portion of the DOM
|
||||
based on an expression. If the expression is false, the element is removed from the DOM.
|
||||
|
||||
|
||||
In this example, the `table` element is removed from the DOM unless the `movies` array has a length greater than zero.
|
||||
td
|
||||
:marked
|
||||
### *ngIf
|
||||
+makeExample('cb-a1-a2-quick-reference/ts/app/movie-list.component.html', 'ngIf')(format="." )
|
||||
:marked
|
||||
The `*ngIf` directive in Angular 2 works the same as the `ng-if` directive in Angular 1,
|
||||
The `*ngIf` directive in Angular 2 works the same as the `ng-if` directive in Angular 1,
|
||||
it removes or recreates a portion of the DOM based on an expression.
|
||||
|
||||
In this example, the `table` element is removed from the DOM unless the `movies` array has a length.
|
||||
|
||||
|
||||
The (*) before `ngIf` is required in this example.
|
||||
For more information see [Structural Directives](../guide/structural-directives.html).
|
||||
tr(style=top)
|
||||
|
@ -309,9 +314,9 @@ table(width="100%")
|
|||
+makeExample('cb-a1-a2-quick-reference/ts/app/movie-list.component.html', 'ngModel')(format="." )
|
||||
:marked
|
||||
In Angular 2, **two-way binding** is denoted with [()], descriptively referred to as a "banana in a box".
|
||||
This syntax is a short-cut for defining both property binding (from the component to the view)
|
||||
This syntax is a short-cut for defining both property binding (from the component to the view)
|
||||
and event binding (from the view to the component), thereby giving us two-way binding.
|
||||
|
||||
|
||||
For more information on two-way binding with ngModel see [Template Syntax](../guide/template-syntax.html#ngModel).
|
||||
tr(style=top)
|
||||
td
|
||||
|
@ -322,23 +327,23 @@ table(width="100%")
|
|||
:marked
|
||||
In Angular 1, the `ng-repeat` directive repeats the associated DOM element
|
||||
for each item from the specified collection.
|
||||
|
||||
|
||||
In this example, the table row (`tr`) element is repeated for each movie object in the collection of movies.
|
||||
td
|
||||
:marked
|
||||
### *ngFor
|
||||
+makeExample('cb-a1-a2-quick-reference/ts/app/movie-list.component.html', 'ngFor')(format="." )
|
||||
:marked
|
||||
The `*ngFor` directive in Angular 2 is similar to the `ng-repeat` directive in Angular 1.
|
||||
The `*ngFor` directive in Angular 2 is similar to the `ng-repeat` directive in Angular 1.
|
||||
It repeats the associated DOM element for each item from the specified collection.
|
||||
More accurately, it turns the defined element (`tr` in this example) and its contents into a template and
|
||||
uses that template to instantiate a view for each item in the list.
|
||||
|
||||
|
||||
Notice the other syntax differences:
|
||||
The (*) before `ngFor` is required;
|
||||
the `let` keyword identifies `movie` as an input variable;
|
||||
the list preposition is `of`, not `in`.
|
||||
|
||||
|
||||
For more information see [Structural Directives](../guide/structural-directives.html).
|
||||
tr(style=top)
|
||||
td
|
||||
|
@ -351,7 +356,7 @@ table(width="100%")
|
|||
:marked
|
||||
In Angular 1, the `ng-show` directive shows or hides the associated DOM element based on
|
||||
an expression.
|
||||
|
||||
|
||||
In this example, the `div` element is shown if the `favoriteHero` variable is truthy.
|
||||
td
|
||||
:marked
|
||||
|
@ -360,12 +365,12 @@ table(width="100%")
|
|||
:marked
|
||||
In Angular 2, we use property binding; there is no built-in *show* directive.
|
||||
For hiding and showing elements, we bind to the HTML `hidden` property.
|
||||
|
||||
To conditionally display an element, place the element's `hidden` property in square brackets and
|
||||
|
||||
To conditionally display an element, place the element's `hidden` property in square brackets and
|
||||
set it to a quoted template expression that evaluates to the *opposite* of *show*.
|
||||
|
||||
In this example, the `div` element is hidden if the `favoriteHero` variable is not truthy.
|
||||
|
||||
|
||||
For more information on property binding see [Template Syntax](../guide/template-syntax.html#property-binding).
|
||||
tr(style=top)
|
||||
td
|
||||
|
@ -384,7 +389,7 @@ table(width="100%")
|
|||
:marked
|
||||
In Angular 2, we use property binding; there is no built-in *src* directive.
|
||||
We place the `src` property in square brackets and set it to a quoted template expression.
|
||||
|
||||
|
||||
For more information on property binding see [Template Syntax](../guide/template-syntax.html#property-binding).
|
||||
tr(style=top)
|
||||
td
|
||||
|
@ -397,28 +402,28 @@ table(width="100%")
|
|||
based on an expression. That expression is often a key-value control object with each
|
||||
key of the object defined as a CSS style name, and each value defined as an expression
|
||||
that evaluates to a value appropriate for the style.
|
||||
|
||||
|
||||
In the example, the `color` style is set to the current value of the `colorPreference` variable.
|
||||
td
|
||||
:marked
|
||||
### ngStyle
|
||||
+makeExample('cb-a1-a2-quick-reference/ts/app/app.component.html', 'ngStyle')(format="." )
|
||||
:marked
|
||||
In Angular 2, the `ngStyle` directive works similarly. It sets a CSS style on an HTML element based on an expression.
|
||||
|
||||
In Angular 2, the `ngStyle` directive works similarly. It sets a CSS style on an HTML element based on an expression.
|
||||
|
||||
In the first example, the `color` style is set to the current value of the `colorPreference` variable.
|
||||
|
||||
|
||||
Angular 2 also has **style binding**, which is good way to set a single style. This is shown in the second example.
|
||||
|
||||
|
||||
For more information on style binding see [Template Syntax](../guide/template-syntax.html#style-binding).
|
||||
|
||||
|
||||
For more information on the ngStyle directive see [Template Syntax](../guide/template-syntax.html#ngStyle).
|
||||
tr(style=top)
|
||||
td
|
||||
:marked
|
||||
### ng-switch
|
||||
code-example(format="").
|
||||
<div ng-switch="vm.favoriteHero &&
|
||||
<div ng-switch="vm.favoriteHero &&
|
||||
vm.checkMovieHero(vm.favoriteHero)">
|
||||
<div ng-switch-when="true">
|
||||
Excellent choice!
|
||||
|
@ -433,7 +438,7 @@ table(width="100%")
|
|||
:marked
|
||||
In Angular 1, the `ng-switch` directive swaps the contents of
|
||||
an element by selecting one of the templates based on the current value of an expression.
|
||||
|
||||
|
||||
In this example, if `favoriteHero` is not set, the template displays "Please enter ...".
|
||||
If the `favoriteHero` is set, it checks the movie hero by calling a controller method.
|
||||
If that method returns `true`, the template displays "Excellent choice!".
|
||||
|
@ -443,21 +448,21 @@ table(width="100%")
|
|||
### ngSwitch
|
||||
+makeExample('cb-a1-a2-quick-reference/ts/app/movie-list.component.html', 'ngSwitch')(format="." )
|
||||
:marked
|
||||
In Angular 2, the `ngSwitch` directive works similarly.
|
||||
In Angular 2, the `ngSwitch` directive works similarly.
|
||||
It displays an element whose `*ngSwitchWhen` matches the current `ngSwitch` expression value.
|
||||
|
||||
|
||||
In this example, if `favoriteHero` is not set, the `ngSwitch` value is `null`
|
||||
and we see the `*ngSwitchDefault` paragraph, "Please enter ...".
|
||||
If the `favoriteHero` is set, it checks the movie hero by calling a component method.
|
||||
If that method returns `true`, we see "Excellent choice!".
|
||||
If that methods returns `false`, we see "No movie, sorry!".
|
||||
|
||||
|
||||
The (*) before `ngSwitchWhen` and `ngSwitchDefault` is required in this example.
|
||||
|
||||
|
||||
For more information on the ngSwitch directive see [Template Syntax](../guide/template-syntax.html#ngSwitch).
|
||||
:marked
|
||||
[Back to top](#top)
|
||||
|
||||
|
||||
a(id="filters-pipes")
|
||||
.l-main-section
|
||||
:marked
|
||||
|
@ -468,7 +473,7 @@ a(id="filters-pipes")
|
|||
|
||||
table(width="100%")
|
||||
col(width="50%")
|
||||
col(width="50%")
|
||||
col(width="50%")
|
||||
tr
|
||||
th Angular 1
|
||||
th Angular 2
|
||||
|
@ -513,9 +518,9 @@ table(width="100%")
|
|||
:marked
|
||||
### none
|
||||
There is no comparable pipe in Angular 2 for performance reasons.
|
||||
Filtering should be coded in the component.
|
||||
Consider building a custom pipe if the same filtering code
|
||||
will be reused in several templates.
|
||||
Filtering should be coded in the component.
|
||||
Consider building a custom pipe if the same filtering code
|
||||
will be reused in several templates.
|
||||
|
||||
tr(style=top)
|
||||
td
|
||||
|
@ -546,7 +551,7 @@ table(width="100%")
|
|||
+makeExample('cb-a1-a2-quick-reference/ts/app/app.component.html', 'slice')(format=".")
|
||||
:marked
|
||||
The `SlicePipe` does the same thing but the *order of the parameters is reversed* in keeping
|
||||
with the JavaScript `Slice` method.
|
||||
with the JavaScript `Slice` method.
|
||||
The first parameter is the starting index; the second is the limit.
|
||||
As in Angular 1, performance may improve if we code this operation within the component instead.
|
||||
tr(style=top)
|
||||
|
@ -577,9 +582,9 @@ table(width="100%")
|
|||
+makeExample('cb-a1-a2-quick-reference/ts/app/app.component.html', 'number')(format=".")
|
||||
:marked
|
||||
The Angular 2 `number` pipe is similar.
|
||||
It provides more functionality when defining
|
||||
It provides more functionality when defining
|
||||
the decimal places as shown in the second example above.
|
||||
|
||||
|
||||
Angular 2 also has a `percent` pipe which formats a number as a local percentage
|
||||
as shown in the third example.
|
||||
tr(style=top)
|
||||
|
@ -589,31 +594,31 @@ table(width="100%")
|
|||
code-example.
|
||||
<tr ng-repeat="movie in movieList | orderBy : 'title'">
|
||||
:marked
|
||||
Orders the collection as specified by the expression.
|
||||
Orders the collection as specified by the expression.
|
||||
In this example, the movieList is ordered by the movie title.
|
||||
td
|
||||
:marked
|
||||
### none
|
||||
There is no comparable pipe in Angular 2 for performance reasons.
|
||||
Ordering/sorting the results should be coded in the component.
|
||||
Consider building a custom pipe if the same ordering/sorting code
|
||||
Ordering/sorting the results should be coded in the component.
|
||||
Consider building a custom pipe if the same ordering/sorting code
|
||||
will be reused in several templates.
|
||||
:marked
|
||||
[Back to top](#top)
|
||||
|
||||
|
||||
a(id="controllers-components")
|
||||
.l-main-section
|
||||
:marked
|
||||
## Controllers / Components
|
||||
In Angular 1, we write the code that provides the model and the methods for the view in a **controller**.
|
||||
In Angular 2, we build a **component**.
|
||||
|
||||
|
||||
Because much of our Angular 1 code is in JavaScript, JavaScript code is shown in the Angular 1 column.
|
||||
The Angular 2 code is shown using TypeScript.
|
||||
|
||||
table(width="100%")
|
||||
col(width="50%")
|
||||
col(width="50%")
|
||||
col(width="50%")
|
||||
tr
|
||||
th Angular 1
|
||||
th Angular 2
|
||||
|
@ -627,13 +632,13 @@ table(width="100%")
|
|||
}());
|
||||
:marked
|
||||
In Angular 1, we often defined an immediately invoked function expression (or IIFE) around our controller code.
|
||||
This kept our controller code out of the global namespace.
|
||||
This kept our controller code out of the global namespace.
|
||||
td
|
||||
:marked
|
||||
### none
|
||||
We don't need to worry about this in Angular 2 because we use ES 2015 modules
|
||||
and modules handle the namespacing for us.
|
||||
|
||||
|
||||
For more information on modules see [Architecture Overview](../guide/architecture.html#module).
|
||||
tr(style=top)
|
||||
td
|
||||
|
@ -652,9 +657,9 @@ table(width="100%")
|
|||
:marked
|
||||
Angular 2 does not have its own module system. Instead we use ES 2015 modules.
|
||||
ES 2015 modules are file based, so each code file is its own module.
|
||||
|
||||
|
||||
We `import` what we need from the module files.
|
||||
|
||||
|
||||
For more information on modules see [Architecture Overview](../guide/architecture.html#module).
|
||||
tr(style=top)
|
||||
td
|
||||
|
@ -668,10 +673,10 @@ table(width="100%")
|
|||
MovieListCtrl]);
|
||||
:marked
|
||||
In Angular 1, we have code in each controller that looks up an appropriate Angular module
|
||||
and registers the controller with that module.
|
||||
|
||||
and registers the controller with that module.
|
||||
|
||||
The first argument is the controller name. The second argument defines the string names of
|
||||
all dependencies injected into this controller, and a reference to the controller function.
|
||||
all dependencies injected into this controller, and a reference to the controller function.
|
||||
td
|
||||
:marked
|
||||
### Component Decorator
|
||||
|
@ -680,9 +685,9 @@ table(width="100%")
|
|||
In Angular 2, we add a decorator to the component class to provide any required metadata.
|
||||
The Component decorator declares that the class is a component and provides metadata about
|
||||
that component, such as its selector (or tag) and its template.
|
||||
|
||||
|
||||
This is how we associate a template with code, which is defined in the component class.
|
||||
|
||||
|
||||
For more information on components see [Architecture Overview](../guide/architecture.html#component).
|
||||
tr(style=top)
|
||||
td
|
||||
|
@ -692,17 +697,17 @@ table(width="100%")
|
|||
function MovieListCtrl(movieService) {
|
||||
}
|
||||
:marked
|
||||
In Angular 1, we write the code for the model and methods in a controller function.
|
||||
In Angular 1, we write the code for the model and methods in a controller function.
|
||||
td
|
||||
:marked
|
||||
### Component class
|
||||
+makeExample('cb-a1-a2-quick-reference/ts/app/movie-list.component.ts', 'class')(format=".")
|
||||
:marked
|
||||
In Angular 2, we create a component class.
|
||||
|
||||
|
||||
NOTE: If you are using TypeScript with Angular 1 then the only difference here is
|
||||
that the component class must be exported using the `export` keyword.
|
||||
|
||||
|
||||
For more information on components see [Architecture Overview](../guide/architecture.html#component).
|
||||
tr(style=top)
|
||||
td
|
||||
|
@ -715,8 +720,8 @@ table(width="100%")
|
|||
:marked
|
||||
In Angular 1, we pass in any dependencies as controller function arguments.
|
||||
In this example, we inject a `MovieService`.
|
||||
|
||||
We also guard against minification problems by telling Angular explicitly
|
||||
|
||||
We also guard against minification problems by telling Angular explicitly
|
||||
that it should inject an instance of the `MovieService` in the first parameter.
|
||||
td
|
||||
:marked
|
||||
|
@ -724,13 +729,13 @@ table(width="100%")
|
|||
+makeExample('cb-a1-a2-quick-reference/ts/app/movie-list.component.ts', 'di')(format=".")
|
||||
:marked
|
||||
In Angular 2, we pass in dependencies as arguments to the component class constructor.
|
||||
In this example, we inject a `MovieService`.
|
||||
In this example, we inject a `MovieService`.
|
||||
The first parameter's TypeScript type tells Angular what to inject even after minification.
|
||||
|
||||
|
||||
For more information on dependency injection see [Architecture Overview](../guide/architecture.html#dependency-injection).
|
||||
:marked
|
||||
[Back to top](#top)
|
||||
|
||||
|
||||
a(id="style-sheets")
|
||||
.l-main-section
|
||||
:marked
|
||||
|
@ -743,7 +748,7 @@ a(id="style-sheets")
|
|||
also encapculate a style sheet within a specific component.
|
||||
table(width="100%")
|
||||
col(width="50%")
|
||||
col(width="50%")
|
||||
col(width="50%")
|
||||
tr
|
||||
th Angular 1
|
||||
th Angular 2
|
||||
|
@ -755,7 +760,7 @@ table(width="100%")
|
|||
<link href="styles.css" rel="stylesheet" />
|
||||
:marked
|
||||
In Angular 1, we use a `link` tag in the head section of our `index.html` file
|
||||
to define the styles for our application.
|
||||
to define the styles for our application.
|
||||
td
|
||||
:marked
|
||||
### Link tag
|
||||
|
@ -765,11 +770,11 @@ table(width="100%")
|
|||
But we can now also encapsulate styles for our components.
|
||||
:marked
|
||||
### StyleUrls
|
||||
In Angular 2, we can use the `styles` or `styleUrls` property of the `@Component` metadata to define
|
||||
In Angular 2, we can use the `styles` or `styleUrls` property of the `@Component` metadata to define
|
||||
a style sheet for a particular component.
|
||||
+makeExample('cb-a1-a2-quick-reference/ts/app/movie-list.component.ts', 'style-url')(format=".")
|
||||
:marked
|
||||
This allows us to set appropriate styles for individual components that won’t leak into
|
||||
This allows us to set appropriate styles for individual components that won’t leak into
|
||||
other parts of the application.
|
||||
:marked
|
||||
[Back to top](#top)
|
||||
|
@ -778,10 +783,10 @@ a(id="string-dates")
|
|||
.l-main-section
|
||||
:marked
|
||||
## Appendix: String dates
|
||||
|
||||
|
||||
Currently the Angular 2 `date` pipe does not process string dates such as
|
||||
"2015-12-19T00:00:00".
|
||||
|
||||
|
||||
As a work around, subclass the Angular `DatePipe` with a version that can convert strings
|
||||
and substitute that pipe in the HTML:
|
||||
|
||||
|
@ -789,7 +794,7 @@ a(id="string-dates")
|
|||
:marked
|
||||
Then import and declare that pipe in the `@Component` metadata `pipes` array:
|
||||
:marked
|
||||
+makeExample('cb-a1-a2-quick-reference/ts/app/movie-list.component.ts', 'date-pipe')(format=".")
|
||||
+makeExample('cb-a1-a2-quick-reference/ts/app/movie-list.component.ts', 'date-pipe')(format=".")
|
||||
|
||||
:marked
|
||||
[Back to top](#top)
|
||||
|
|
|
@ -3,50 +3,82 @@ include ../_util-fns
|
|||
:marked
|
||||
## Write *Component-Relative* URLs to component templates and style files
|
||||
|
||||
## 为组件模板和样式表文件写*相对于组件的*URL
|
||||
|
||||
Our components often refer to external template and style files.
|
||||
We identify those files with a URL in the `templateUrl` and `styleUrls` properties of the `@Component` metadata
|
||||
as seen here:
|
||||
|
||||
|
||||
我们的组件通常都是引用外部的模板和样式表文件。
|
||||
我们在`@Component`的元数据中通过`templateUrl`和`styleUrls`属性来标识出它们的位置:
|
||||
|
||||
+makeExample('cb-component-relative-paths/ts/app/some.component.ts','absolute-config')(format='.')
|
||||
:marked
|
||||
By default, we *must* specify the full path back to the application root.
|
||||
We call this an ***absolute path*** because it is *absolute* with respect to the application root.
|
||||
|
||||
默认情况下,我们*必须*指定一个到应用根目录的完整路径。
|
||||
我们称之为***绝对路径***,因为如果以应用程序的根目录为基准来看,它就是*绝对路径*。
|
||||
|
||||
There are two problems with an *absolute path*:
|
||||
|
||||
|
||||
使用*绝对路径*有两个问题:
|
||||
|
||||
1. We have to remember the full path back to the application root.
|
||||
|
||||
|
||||
1. 我们不得不记住到应用程序根目录的完整路径。
|
||||
|
||||
1. We have to update the URL when we move the component around in the application files structure.
|
||||
|
||||
|
||||
1. 当我们在应用的文件结构中移动这个组件时,将不得不更新这个URL
|
||||
|
||||
It would be much easier to write and maintain our application components if we could specify template and style locations
|
||||
*relative* to their component class file.
|
||||
|
||||
|
||||
如果我们能用*相对*于组件类文件的路径来指定模板和样式表的位置,那么编写和维护组件就会变得容易得多。
|
||||
|
||||
*We can!*
|
||||
|
||||
|
||||
*没问题!*
|
||||
|
||||
.alert.is-important
|
||||
:marked
|
||||
We can if we build our application as `commonjs` modules and load those modules
|
||||
with a suitable package loader such as `systemjs` or `webpack`.
|
||||
Learn why [below](#why-default).
|
||||
|
||||
|
||||
如果我们把应用构建成`commonjs`模块,并用一个合适的包加载器(比如`systemjs`或`webpack`)加载那些模块,就可以了。
|
||||
[在下方](#why-default)可以学到原理。
|
||||
|
||||
The Angular 2 CLI uses these technologies and defaults to the
|
||||
*component-relative path* approach described here.
|
||||
CLI users can skip this chapter or read on to understand
|
||||
how it works.
|
||||
|
||||
|
||||
Angular 2 CLI(命令行界面)使用这些技术,并默认采用这里所说的*组件相对路径*方法。
|
||||
用CLI用户可以跳过本章,并且往后阅读来了解它是怎么工作的。
|
||||
|
||||
.l-main-section
|
||||
:marked
|
||||
## _Component-Relative_ Paths
|
||||
|
||||
Our goal is to specify template and style URLs *relative* to their component class files,
|
||||
## _组件相对_路径
|
||||
|
||||
Our goal is to specify template and style URLs *relative* to their component class files,
|
||||
hence the term ***component-relative path***.
|
||||
|
||||
|
||||
我们的目标是指定*相对*于组件类的模板和样式表的URL,因此得名***组件相对路径***。
|
||||
|
||||
The key to success is following a convention that puts related component files in well-known locations.
|
||||
|
||||
|
||||
成功的关键是遵循一个约定:把相对组件的文件放进众所周知的位置。
|
||||
|
||||
We recommend keeping component template and component-specific style files as *siblings* of their
|
||||
companion component class files.
|
||||
Here we see the three files for `SomeComponent` sitting next to each other in the `app` folder.
|
||||
|
||||
companion component class files.
|
||||
Here we see the three files for `SomeComponent` sitting next to each other in the `app` folder.
|
||||
|
||||
我们建议把组件的模板和组件特有的样式表文件作为组件类文件的“兄弟”。
|
||||
这里我们看到在`app`目录下依次有`SomeComponent`的三个文件。
|
||||
|
||||
.filetree
|
||||
.file app
|
||||
.children
|
||||
|
@ -57,27 +89,45 @@ include ../_util-fns
|
|||
:marked
|
||||
We'll have more files and folders — and greater folder depth — as our application grows.
|
||||
We'll be fine as long as the component files travel together as the inseparable siblings they are.
|
||||
|
||||
|
||||
当应用规模增长后,我们还会有更多的文件和目录以及更大的深度。
|
||||
如果组件的所有文件总是像形影不离的兄弟那样共进退,那该多好啊!
|
||||
|
||||
### Set the *moduleId*
|
||||
|
||||
### 设置*moduleId*
|
||||
|
||||
Having adopted this file structure convention, we can specify locations of the template and style files
|
||||
relative to the component class file simply by setting the `moduleId` property of the `@Component` metadata like this
|
||||
|
||||
采用这种文件结构约定,我们可以为模板和样式表文件指定相对于组件类文件的位置 —— 只要简单的在`@Component`元数据中设置`moduleId`属性就可以了,就像这样:
|
||||
|
||||
+makeExample('cb-component-relative-paths/ts/app/some.component.ts','module-id')(format='.')
|
||||
:marked
|
||||
We strip the `app/` base path from the `templateUrl` and `styleUrls`. The result looks like this:
|
||||
|
||||
我们从`templateUrl`和`styleUrls`中把基准路径`app/`去掉了。结果是这样的:
|
||||
|
||||
+makeExample('cb-component-relative-paths/ts/app/some.component.ts','relative-config')(format='.')
|
||||
|
||||
.alert.is-helpful
|
||||
:marked
|
||||
Webpack users may prefer [an alternative approach](#webpack) that uses `require`.
|
||||
|
||||
|
||||
Webpack用户可能更喜欢[一个替代方案](#webpack):使用`require`。
|
||||
|
||||
.l-main-section
|
||||
:marked
|
||||
## Source
|
||||
|
||||
|
||||
## 源码
|
||||
|
||||
**We can see the [live example](/resources/live-examples/cb-component-relative-paths/ts/plnkr.html)**
|
||||
and download the source code from there
|
||||
or simply read the pertinent source here.
|
||||
|
||||
**我们可以参见[在线范例](/resources/live-examples/cb-component-relative-paths/ts/plnkr.html)**
|
||||
并从中下载源码或只在这里阅读相关源码。
|
||||
|
||||
+makeTabs(
|
||||
`cb-component-relative-paths/ts/app/some.component.ts,
|
||||
cb-component-relative-paths/ts/app/some.component.html,
|
||||
|
@ -90,51 +140,90 @@ a#why-default
|
|||
.l-main-section
|
||||
:marked
|
||||
## Appendix: why *component-relative* is not the default
|
||||
## 附录:为什么*组件相对路径*不是默认方式
|
||||
|
||||
A *component-relative* path is obviously superior to an *absolute* path.
|
||||
Why did Angular default to the *absolute* path?
|
||||
Why do *we* have to set the `moduleId`? Why can't Angular set it?
|
||||
|
||||
|
||||
*组件相对路径*明显比*绝对路径*高级一点。
|
||||
为什么Angular默认采用了*绝对路径*呢?
|
||||
为什么*我们*不得不设置`moduleId`呢?Angular为什么不能自己设置它?
|
||||
|
||||
First, let's look at what happens if we use a relative path and omit the `moduleId`.
|
||||
|
||||
|
||||
首先,如果只使用相对路径而省略掉`moduleId`,我们来看看会发生什么。
|
||||
|
||||
`EXCEPTION: Failed to load some.component.html`
|
||||
|
||||
`EXCEPTION: Failed to load some.component.html`
|
||||
|
||||
Angular can't find the file so it throws an error.
|
||||
|
||||
Why can't Angular calculate the template and style URLs from the component file's location?
|
||||
|
||||
Angular找不到这个文件,所以它抛出一个错误。
|
||||
|
||||
Why can't Angular calculate the template and style URLs from the component file's location?
|
||||
|
||||
为什么Angular不能相对于组件类文件的路径来自动计算模板和样式表的URL呢?
|
||||
|
||||
Because the location of the component can't be determined without the developer's help.
|
||||
Angular apps can be loaded in many ways: from individual files, from SystemJS packages, or
|
||||
from CommonJS packages, to name a few.
|
||||
We might generate modules in any of several formats.
|
||||
from CommonJS packages, to name a few.
|
||||
We might generate modules in any of several formats.
|
||||
We might not be writing modular code at all!
|
||||
|
||||
With this diversity of packaging and module load strategies,
|
||||
|
||||
因为如果没有开发人员的帮助,组件的位置是检测不到的。
|
||||
Angular应用可能被用多种方式加载:SystemJS包、CommonJS包等等。
|
||||
我们可能会用几种格式之一来生成模块。
|
||||
我们甚至可能完全没有写成模块化代码。
|
||||
|
||||
With this diversity of packaging and module load strategies,
|
||||
it's not possible for Angular to know with certainty where these files reside at runtime.
|
||||
|
||||
由于存在这么多打包和模块加载策略,所以Angular不可能知道在运行期这些文件的正确位置。
|
||||
|
||||
The only location Angular can be sure of is the URL of the `index.html` home page, the application root.
|
||||
So by default it resolves template and style paths relative to the URL of `index.html`.
|
||||
That's why we previously wrote our file URLs with an `app/` base path prefix.
|
||||
|
||||
Angular能够确定的唯一的位置是首页`index.html`的URL,也就是应用的根目录。
|
||||
所以,默认情况下,它只能计算相对于`index.html`的模板和样式表路径。
|
||||
这就是为什么我们以前用`app/`基准路径的前缀来写文件的URL。
|
||||
|
||||
But *if* we follow the recommended guidelines and we write modules in `commonjs` format
|
||||
and we use a module loader that *plays nice*,
|
||||
*then* we — the developers of the application —
|
||||
know that the semi-global `module.id` variable is available and contains
|
||||
the absolute URL of the component class module file.
|
||||
|
||||
|
||||
但是,*如果*我们遵循了建议的指导原则,用`commonjs`格式编写模块,并使用一个*不错的*模块加载器,
|
||||
那么我们这些应用开发人员就能知道存在一个可用的半全局变量`module.id`,并且其中包含着组件类模块文件的绝对URL。
|
||||
|
||||
That knowledge enables us to tell Angular where the *component* file is
|
||||
by setting the `moduleId`:
|
||||
|
||||
这种认知让我们得以通过设置`moduleId`来告诉Angular*组件类*文件在哪里:
|
||||
|
||||
+makeExample('cb-component-relative-paths/ts/app/some.component.ts','module-id')(format='.')
|
||||
|
||||
a#webpack
|
||||
.l-main-section
|
||||
:marked
|
||||
## Webpack: load templates and styles with *require*
|
||||
|
||||
## Webpack: 使用*require*加载模板和样式表
|
||||
|
||||
Webpack developers have an alternative to `moduleId`.
|
||||
|
||||
|
||||
Webpack开发者有`moduleId`的另一个备选方案。
|
||||
|
||||
They can load templates and styles at runtime by setting the component metadata `template` and `style` properties
|
||||
with `require` statements that reference *component-relative* URLS.
|
||||
|
||||
|
||||
通过把组件元数据中的`template`和`style`属性设置为`require`语句,并引用一个*相对于组件的*URL,他们可以在运行期间加载模板和样式表。
|
||||
|
||||
+makeExample('webpack/ts/src/app/app.component.ts')(format='.')
|
||||
:marked
|
||||
See the [Introduction to Webpack](../guide/webpack.html).
|
||||
|
||||
参见[Webpack简介](../guide/webpack.html)。
|
||||
|
|
|
@ -71,7 +71,7 @@ a#hooks-overview
|
|||
:marked
|
||||
## Component lifecycle Hooks
|
||||
|
||||
##组件生命周期钩子
|
||||
## 组件生命周期钩子
|
||||
|
||||
Directive and component instances have a lifecycle
|
||||
as Angular creates, updates, and destroys them.
|
||||
|
|
Loading…
Reference in New Issue