Compare commits
3 Commits
master
...
guide/libr
Author | SHA1 | Date | |
---|---|---|---|
![]() |
5d8f869913 | ||
![]() |
2ca7ee8f54 | ||
![]() |
f8c56ec8eb |
@ -1,665 +0,0 @@
|
|||||||
# Ahead-of-time (AOT) compilation
|
|
||||||
|
|
||||||
An Angular application consists mainly of components and their HTML templates. Because the components and templates provided by Angular cannot be understood by the browser directly, Angular applications require a compilation process before they can run in a browser.
|
|
||||||
|
|
||||||
The Angular [ahead-of-time (AOT) compiler](guide/glossary#aot) converts your Angular HTML and TypeScript code into efficient JavaScript code during the build phase _before_ the browser downloads and runs that code. Compiling your application during the build process provides a faster rendering in the browser.
|
|
||||||
|
|
||||||
This guide explains how to specify metadata and apply available compiler options to compile your applications efficiently using the AOT compiler.
|
|
||||||
|
|
||||||
<div class="alert is-helpful">
|
|
||||||
|
|
||||||
<a href="https://www.youtube.com/watch?v=anphffaCZrQ">Watch Alex Rickabaugh explain the Angular compiler</a> at AngularConnect 2019.
|
|
||||||
|
|
||||||
</div>
|
|
||||||
|
|
||||||
{@a why-aot}
|
|
||||||
|
|
||||||
Here are some reasons you might want to use AOT.
|
|
||||||
|
|
||||||
* *Faster rendering*
|
|
||||||
With AOT, the browser downloads a pre-compiled version of the application.
|
|
||||||
The browser loads executable code so it can render the application immediately, without waiting to compile the app first.
|
|
||||||
|
|
||||||
* *Fewer asynchronous requests*
|
|
||||||
The compiler _inlines_ external HTML templates and CSS style sheets within the application JavaScript,
|
|
||||||
eliminating separate ajax requests for those source files.
|
|
||||||
|
|
||||||
* *Smaller Angular framework download size*
|
|
||||||
There's no need to download the Angular compiler if the app is already compiled.
|
|
||||||
The compiler is roughly half of Angular itself, so omitting it dramatically reduces the application payload.
|
|
||||||
|
|
||||||
* *Detect template errors earlier*
|
|
||||||
The AOT compiler detects and reports template binding errors during the build step
|
|
||||||
before users can see them.
|
|
||||||
|
|
||||||
* *Better security*
|
|
||||||
AOT compiles HTML templates and components into JavaScript files long before they are served to the client.
|
|
||||||
With no templates to read and no risky client-side HTML or JavaScript evaluation,
|
|
||||||
there are fewer opportunities for injection attacks.
|
|
||||||
|
|
||||||
{@a overview}
|
|
||||||
|
|
||||||
## Choosing a compiler
|
|
||||||
|
|
||||||
Angular offers two ways to compile your application:
|
|
||||||
|
|
||||||
* **_Just-in-Time_ (JIT)**, which compiles your app in the browser at runtime. This was the default until Angular 8.
|
|
||||||
* **_Ahead-of-Time_ (AOT)**, which compiles your app and libraries at build time. This is the default since Angular 9.
|
|
||||||
|
|
||||||
When you run the [`ng build`](cli/build) (build only) or [`ng serve`](cli/serve) (build and serve locally) CLI commands, the type of compilation (JIT or AOT) depends on the value of the `aot` property in your build configuration specified in `angular.json`. By default, `aot` is set to `true` for new CLI apps.
|
|
||||||
|
|
||||||
See the [CLI command reference](cli) and [Building and serving Angular apps](guide/build) for more information.
|
|
||||||
|
|
||||||
## How AOT works
|
|
||||||
|
|
||||||
The Angular AOT compiler extracts **metadata** to interpret the parts of the application that Angular is supposed to manage.
|
|
||||||
You can specify the metadata explicitly in **decorators** such as `@Component()` and `@Input()`, or implicitly in the constructor declarations of the decorated classes.
|
|
||||||
The metadata tells Angular how to construct instances of your application classes and interact with them at runtime.
|
|
||||||
|
|
||||||
In the following example, the `@Component()` metadata object and the class constructor tell Angular how to create and display an instance of `TypicalComponent`.
|
|
||||||
|
|
||||||
```typescript
|
|
||||||
@Component({
|
|
||||||
selector: 'app-typical',
|
|
||||||
template: '<div>A typical component for {{data.name}}</div>'
|
|
||||||
)}
|
|
||||||
export class TypicalComponent {
|
|
||||||
@Input() data: TypicalData;
|
|
||||||
constructor(private someService: SomeService) { ... }
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
The Angular compiler extracts the metadata _once_ and generates a _factory_ for `TypicalComponent`.
|
|
||||||
When it needs to create a `TypicalComponent` instance, Angular calls the factory, which produces a new visual element, bound to a new instance of the component class with its injected dependency.
|
|
||||||
|
|
||||||
### Compilation phases
|
|
||||||
|
|
||||||
There are three phases of AOT compilation.
|
|
||||||
* Phase 1 is *code analysis*.
|
|
||||||
In this phase, the TypeScript compiler and *AOT collector* create a representation of the source. The collector does not attempt to interpret the metadata it collects. It represents the metadata as best it can and records errors when it detects a metadata syntax violation.
|
|
||||||
|
|
||||||
* Phase 2 is *code generation*.
|
|
||||||
In this phase, the compiler's `StaticReflector` interprets the metadata collected in phase 1, performs additional validation of the metadata, and throws an error if it detects a metadata restriction violation.
|
|
||||||
|
|
||||||
* Phase 3 is *template type checking*.
|
|
||||||
In this optional phase, the Angular *template compiler* uses the TypeScript compiler to validate the binding expressions in templates. You can enable this phase explicitly by setting the `fullTemplateTypeCheck` configuration option; see [Angular compiler options](guide/angular-compiler-options).
|
|
||||||
|
|
||||||
|
|
||||||
### Metadata restrictions
|
|
||||||
|
|
||||||
You write metadata in a _subset_ of TypeScript that must conform to the following general constraints:
|
|
||||||
|
|
||||||
* Limit [expression syntax](#expression-syntax) to the supported subset of JavaScript.
|
|
||||||
* Only reference exported symbols after [code folding](#code-folding).
|
|
||||||
* Only call [functions supported](#supported-functions) by the compiler.
|
|
||||||
* Decorated and data-bound class members must be public.
|
|
||||||
|
|
||||||
For additional guidelines and instructions on preparing an application for AOT compilation, see [Angular: Writing AOT-friendly applications](https://medium.com/sparkles-blog/angular-writing-aot-friendly-applications-7b64c8afbe3f).
|
|
||||||
|
|
||||||
<div class="alert is-helpful">
|
|
||||||
|
|
||||||
Errors in AOT compilation commonly occur because of metadata that does not conform to the compiler's requirements (as described more fully below).
|
|
||||||
For help in understanding and resolving these problems, see [AOT Metadata Errors](guide/aot-metadata-errors).
|
|
||||||
|
|
||||||
</div>
|
|
||||||
|
|
||||||
### Configuring AOT compilation
|
|
||||||
|
|
||||||
You can provide options in the [TypeScript configuration file](guide/typescript-configuration) that controls the compilation process. See [Angular compiler options](guide/angular-compiler-options) for a complete list of available options.
|
|
||||||
|
|
||||||
## Phase 1: Code analysis
|
|
||||||
|
|
||||||
The TypeScript compiler does some of the analytic work of the first phase. It emits the `.d.ts` _type definition files_ with type information that the AOT compiler needs to generate application code.
|
|
||||||
At the same time, the AOT **collector** analyzes the metadata recorded in the Angular decorators and outputs metadata information in **`.metadata.json`** files, one per `.d.ts` file.
|
|
||||||
|
|
||||||
You can think of `.metadata.json` as a diagram of the overall structure of a decorator's metadata, represented as an [abstract syntax tree (AST)](https://en.wikipedia.org/wiki/Abstract_syntax_tree).
|
|
||||||
|
|
||||||
<div class="alert is-helpful">
|
|
||||||
|
|
||||||
Angular's [schema.ts](https://github.com/angular/angular/blob/master/packages/compiler-cli/src/metadata/schema.ts)
|
|
||||||
describes the JSON format as a collection of TypeScript interfaces.
|
|
||||||
|
|
||||||
</div>
|
|
||||||
|
|
||||||
{@a expression-syntax}
|
|
||||||
### Expression syntax limitations
|
|
||||||
|
|
||||||
The AOT collector only understands a subset of JavaScript.
|
|
||||||
Define metadata objects with the following limited syntax:
|
|
||||||
|
|
||||||
<style>
|
|
||||||
td, th {vertical-align: top}
|
|
||||||
</style>
|
|
||||||
|
|
||||||
<table>
|
|
||||||
<tr>
|
|
||||||
<th>Syntax</th>
|
|
||||||
<th>Example</th>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>Literal object </td>
|
|
||||||
<td><code>{cherry: true, apple: true, mincemeat: false}</code></td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>Literal array </td>
|
|
||||||
<td><code>['cherries', 'flour', 'sugar']</code></td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>Spread in literal array</td>
|
|
||||||
<td><code>['apples', 'flour', ...the_rest]</code></td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>Calls</td>
|
|
||||||
<td><code>bake(ingredients)</code></td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>New</td>
|
|
||||||
<td><code>new Oven()</code></td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>Property access</td>
|
|
||||||
<td><code>pie.slice</code></td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>Array index</td>
|
|
||||||
<td><code>ingredients[0]</code></td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>Identity reference</td>
|
|
||||||
<td><code>Component</code></td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>A template string</td>
|
|
||||||
<td><code>`pie is ${multiplier} times better than cake`</code></td>
|
|
||||||
<tr>
|
|
||||||
<td>Literal string</td>
|
|
||||||
<td><code>pi</code></td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>Literal number</td>
|
|
||||||
<td><code>3.14153265</code></td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>Literal boolean</td>
|
|
||||||
<td><code>true</code></td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>Literal null</td>
|
|
||||||
<td><code>null</code></td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>Supported prefix operator </td>
|
|
||||||
<td><code>!cake</code></td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>Supported binary operator </td>
|
|
||||||
<td><code>a+b</code></td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>Conditional operator</td>
|
|
||||||
<td><code>a ? b : c</code></td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>Parentheses</td>
|
|
||||||
<td><code>(a+b)</code></td>
|
|
||||||
</tr>
|
|
||||||
</table>
|
|
||||||
|
|
||||||
|
|
||||||
If an expression uses unsupported syntax, the collector writes an error node to the `.metadata.json` file.
|
|
||||||
The compiler later reports the error if it needs that piece of metadata to generate the application code.
|
|
||||||
|
|
||||||
<div class="alert is-helpful">
|
|
||||||
|
|
||||||
If you want `ngc` to report syntax errors immediately rather than produce a `.metadata.json` file with errors, set the `strictMetadataEmit` option in the TypeScript configuration file.
|
|
||||||
|
|
||||||
```
|
|
||||||
"angularCompilerOptions": {
|
|
||||||
...
|
|
||||||
"strictMetadataEmit" : true
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
Angular libraries have this option to ensure that all Angular `.metadata.json` files are clean and it is a best practice to do the same when building your own libraries.
|
|
||||||
|
|
||||||
</div>
|
|
||||||
|
|
||||||
{@a function-expression}
|
|
||||||
{@a arrow-functions}
|
|
||||||
### No arrow functions
|
|
||||||
|
|
||||||
The AOT compiler does not support [function expressions](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/function)
|
|
||||||
and [arrow functions](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/Arrow_functions), also called _lambda_ functions.
|
|
||||||
|
|
||||||
Consider the following component decorator:
|
|
||||||
|
|
||||||
```typescript
|
|
||||||
@Component({
|
|
||||||
...
|
|
||||||
providers: [{provide: server, useFactory: () => new Server()}]
|
|
||||||
})
|
|
||||||
```
|
|
||||||
|
|
||||||
The AOT collector does not support the arrow function, `() => new Server()`, in a metadata expression.
|
|
||||||
It generates an error node in place of the function.
|
|
||||||
When the compiler later interprets this node, it reports an error that invites you to turn the arrow function into an _exported function_.
|
|
||||||
|
|
||||||
You can fix the error by converting to this:
|
|
||||||
|
|
||||||
```typescript
|
|
||||||
export function serverFactory() {
|
|
||||||
return new Server();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Component({
|
|
||||||
...
|
|
||||||
providers: [{provide: server, useFactory: serverFactory}]
|
|
||||||
})
|
|
||||||
```
|
|
||||||
|
|
||||||
In version 5 and later, the compiler automatically performs this rewriting while emitting the `.js` file.
|
|
||||||
|
|
||||||
{@a exported-symbols}
|
|
||||||
{@a code-folding}
|
|
||||||
### Code folding
|
|
||||||
|
|
||||||
The compiler can only resolve references to **_exported_** symbols.
|
|
||||||
The collector, however, can evaluate an expression during collection and record the result in the `.metadata.json`, rather than the original expression.
|
|
||||||
This allows you to make limited use of non-exported symbols within expressions.
|
|
||||||
|
|
||||||
For example, the collector can evaluate the expression `1 + 2 + 3 + 4` and replace it with the result, `10`.
|
|
||||||
This process is called _folding_. An expression that can be reduced in this manner is _foldable_.
|
|
||||||
|
|
||||||
{@a var-declaration}
|
|
||||||
The collector can evaluate references to module-local `const` declarations and initialized `var` and `let` declarations, effectively removing them from the `.metadata.json` file.
|
|
||||||
|
|
||||||
Consider the following component definition:
|
|
||||||
|
|
||||||
```typescript
|
|
||||||
const template = '<div>{{hero.name}}</div>';
|
|
||||||
|
|
||||||
@Component({
|
|
||||||
selector: 'app-hero',
|
|
||||||
template: template
|
|
||||||
})
|
|
||||||
export class HeroComponent {
|
|
||||||
@Input() hero: Hero;
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
The compiler could not refer to the `template` constant because it isn't exported.
|
|
||||||
The collector, however, can fold the `template` constant into the metadata definition by in-lining its contents.
|
|
||||||
The effect is the same as if you had written:
|
|
||||||
|
|
||||||
```typescript
|
|
||||||
@Component({
|
|
||||||
selector: 'app-hero',
|
|
||||||
template: '<div>{{hero.name}}</div>'
|
|
||||||
})
|
|
||||||
export class HeroComponent {
|
|
||||||
@Input() hero: Hero;
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
There is no longer a reference to `template` and, therefore, nothing to trouble the compiler when it later interprets the _collector's_ output in `.metadata.json`.
|
|
||||||
|
|
||||||
You can take this example a step further by including the `template` constant in another expression:
|
|
||||||
|
|
||||||
```typescript
|
|
||||||
const template = '<div>{{hero.name}}</div>';
|
|
||||||
|
|
||||||
@Component({
|
|
||||||
selector: 'app-hero',
|
|
||||||
template: template + '<div>{{hero.title}}</div>'
|
|
||||||
})
|
|
||||||
export class HeroComponent {
|
|
||||||
@Input() hero: Hero;
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
The collector reduces this expression to its equivalent _folded_ string:
|
|
||||||
|
|
||||||
```
|
|
||||||
'<div>{{hero.name}}</div><div>{{hero.title}}</div>'
|
|
||||||
```
|
|
||||||
|
|
||||||
#### Foldable syntax
|
|
||||||
|
|
||||||
The following table describes which expressions the collector can and cannot fold:
|
|
||||||
|
|
||||||
<style>
|
|
||||||
td, th {vertical-align: top}
|
|
||||||
</style>
|
|
||||||
|
|
||||||
<table>
|
|
||||||
<tr>
|
|
||||||
<th>Syntax</th>
|
|
||||||
<th>Foldable</th>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>Literal object </td>
|
|
||||||
<td>yes</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>Literal array </td>
|
|
||||||
<td>yes</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>Spread in literal array</td>
|
|
||||||
<td>no</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>Calls</td>
|
|
||||||
<td>no</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>New</td>
|
|
||||||
<td>no</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>Property access</td>
|
|
||||||
<td>yes, if target is foldable</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>Array index</td>
|
|
||||||
<td> yes, if target and index are foldable</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>Identity reference</td>
|
|
||||||
<td>yes, if it is a reference to a local</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>A template with no substitutions</td>
|
|
||||||
<td>yes</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>A template with substitutions</td>
|
|
||||||
<td>yes, if the substitutions are foldable</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>Literal string</td>
|
|
||||||
<td>yes</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>Literal number</td>
|
|
||||||
<td>yes</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>Literal boolean</td>
|
|
||||||
<td>yes</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>Literal null</td>
|
|
||||||
<td>yes</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>Supported prefix operator </td>
|
|
||||||
<td>yes, if operand is foldable</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>Supported binary operator </td>
|
|
||||||
<td>yes, if both left and right are foldable</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>Conditional operator</td>
|
|
||||||
<td>yes, if condition is foldable </td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>Parentheses</td>
|
|
||||||
<td>yes, if the expression is foldable</td>
|
|
||||||
</tr>
|
|
||||||
</table>
|
|
||||||
|
|
||||||
|
|
||||||
If an expression is not foldable, the collector writes it to `.metadata.json` as an [AST](https://en.wikipedia.org/wiki/Abstract_syntax_tree) for the compiler to resolve.
|
|
||||||
|
|
||||||
|
|
||||||
## Phase 2: code generation
|
|
||||||
|
|
||||||
The collector makes no attempt to understand the metadata that it collects and outputs to `.metadata.json`.
|
|
||||||
It represents the metadata as best it can and records errors when it detects a metadata syntax violation.
|
|
||||||
It's the compiler's job to interpret the `.metadata.json` in the code generation phase.
|
|
||||||
|
|
||||||
The compiler understands all syntax forms that the collector supports, but it may reject _syntactically_ correct metadata if the _semantics_ violate compiler rules.
|
|
||||||
|
|
||||||
### Public symbols
|
|
||||||
|
|
||||||
The compiler can only reference _exported symbols_.
|
|
||||||
|
|
||||||
* Decorated component class members must be public. You cannot make an `@Input()` property private or protected.
|
|
||||||
* Data bound properties must also be public.
|
|
||||||
|
|
||||||
```typescript
|
|
||||||
// BAD CODE - title is private
|
|
||||||
@Component({
|
|
||||||
selector: 'app-root',
|
|
||||||
template: '<h1>{{title}}</h1>'
|
|
||||||
})
|
|
||||||
export class AppComponent {
|
|
||||||
private title = 'My App'; // Bad
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
{@a supported-functions}
|
|
||||||
|
|
||||||
### Supported classes and functions
|
|
||||||
|
|
||||||
The collector can represent a function call or object creation with `new` as long as the syntax is valid.
|
|
||||||
The compiler, however, can later refuse to generate a call to a _particular_ function or creation of a _particular_ object.
|
|
||||||
|
|
||||||
The compiler can only create instances of certain classes, supports only core decorators, and only supports calls to macros (functions or static methods) that return expressions.
|
|
||||||
* New instances
|
|
||||||
|
|
||||||
The compiler only allows metadata that create instances of the class `InjectionToken` from `@angular/core`.
|
|
||||||
|
|
||||||
* Supported decorators
|
|
||||||
|
|
||||||
The compiler only supports metadata for the [Angular decorators in the `@angular/core` module](api/core#decorators).
|
|
||||||
|
|
||||||
* Function calls
|
|
||||||
|
|
||||||
Factory functions must be exported, named functions.
|
|
||||||
The AOT compiler does not support lambda expressions ("arrow functions") for factory functions.
|
|
||||||
|
|
||||||
{@a function-calls}
|
|
||||||
### Functions and static method calls
|
|
||||||
|
|
||||||
The collector accepts any function or static method that contains a single `return` statement.
|
|
||||||
The compiler, however, only supports macros in the form of functions or static methods that return an *expression*.
|
|
||||||
|
|
||||||
For example, consider the following function:
|
|
||||||
|
|
||||||
```typescript
|
|
||||||
export function wrapInArray<T>(value: T): T[] {
|
|
||||||
return [value];
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
You can call the `wrapInArray` in a metadata definition because it returns the value of an expression that conforms to the compiler's restrictive JavaScript subset.
|
|
||||||
|
|
||||||
You might use `wrapInArray()` like this:
|
|
||||||
|
|
||||||
```typescript
|
|
||||||
@NgModule({
|
|
||||||
declarations: wrapInArray(TypicalComponent)
|
|
||||||
})
|
|
||||||
export class TypicalModule {}
|
|
||||||
```
|
|
||||||
|
|
||||||
The compiler treats this usage as if you had written:
|
|
||||||
|
|
||||||
```typescript
|
|
||||||
@NgModule({
|
|
||||||
declarations: [TypicalComponent]
|
|
||||||
})
|
|
||||||
export class TypicalModule {}
|
|
||||||
```
|
|
||||||
The Angular [`RouterModule`](api/router/RouterModule) exports two macro static methods, `forRoot` and `forChild`, to help declare root and child routes.
|
|
||||||
Review the [source code](https://github.com/angular/angular/blob/master/packages/router/src/router_module.ts#L139 "RouterModule.forRoot source code")
|
|
||||||
for these methods to see how macros can simplify configuration of complex [NgModules](guide/ngmodules).
|
|
||||||
|
|
||||||
{@a metadata-rewriting}
|
|
||||||
|
|
||||||
### Metadata rewriting
|
|
||||||
|
|
||||||
The compiler treats object literals containing the fields `useClass`, `useValue`, `useFactory`, and `data` specially, converting the expression initializing one of these fields into an exported variable that replaces the expression.
|
|
||||||
This process of rewriting these expressions removes all the restrictions on what can be in them because
|
|
||||||
the compiler doesn't need to know the expression's value—it just needs to be able to generate a reference to the value.
|
|
||||||
|
|
||||||
You might write something like:
|
|
||||||
|
|
||||||
```typescript
|
|
||||||
class TypicalServer {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@NgModule({
|
|
||||||
providers: [{provide: SERVER, useFactory: () => TypicalServer}]
|
|
||||||
})
|
|
||||||
export class TypicalModule {}
|
|
||||||
```
|
|
||||||
|
|
||||||
Without rewriting, this would be invalid because lambdas are not supported and `TypicalServer` is not exported.
|
|
||||||
To allow this, the compiler automatically rewrites this to something like:
|
|
||||||
|
|
||||||
```typescript
|
|
||||||
class TypicalServer {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
export const ɵ0 = () => new TypicalServer();
|
|
||||||
|
|
||||||
@NgModule({
|
|
||||||
providers: [{provide: SERVER, useFactory: ɵ0}]
|
|
||||||
})
|
|
||||||
export class TypicalModule {}
|
|
||||||
```
|
|
||||||
|
|
||||||
This allows the compiler to generate a reference to `ɵ0` in the factory without having to know what the value of `ɵ0` contains.
|
|
||||||
|
|
||||||
The compiler does the rewriting during the emit of the `.js` file.
|
|
||||||
It does not, however, rewrite the `.d.ts` file, so TypeScript doesn't recognize it as being an export. and it does not interfere with the ES module's exported API.
|
|
||||||
|
|
||||||
|
|
||||||
{@a binding-expression-validation}
|
|
||||||
|
|
||||||
## Phase 3: Template type checking
|
|
||||||
|
|
||||||
One of the Angular compiler's most helpful features is the ability to type-check expressions within templates, and catch any errors before they cause crashes at runtime.
|
|
||||||
In the template type-checking phase, the Angular template compiler uses the TypeScript compiler to validate the binding expressions in templates.
|
|
||||||
|
|
||||||
Enable this phase explicitly by adding the compiler option `"fullTemplateTypeCheck"` in the `"angularCompilerOptions"` of the project's TypeScript configuration file
|
|
||||||
(see [Angular Compiler Options](guide/angular-compiler-options)).
|
|
||||||
|
|
||||||
<div class="alert is-helpful">
|
|
||||||
|
|
||||||
In [Angular Ivy](guide/ivy), the template type checker has been completely rewritten to be more capable as well as stricter, meaning it can catch a variety of new errors that the previous type checker would not detect.
|
|
||||||
|
|
||||||
As a result, templates that previously compiled under View Engine can fail type checking under Ivy. This can happen because Ivy's stricter checking catches genuine errors, or because application code is not typed correctly, or because the application uses libraries in which typings are inaccurate or not specific enough.
|
|
||||||
|
|
||||||
This stricter type checking is not enabled by default in version 9, but can be enabled by setting the `strictTemplates` configuration option.
|
|
||||||
We do expect to make strict type checking the default in the future.
|
|
||||||
|
|
||||||
For more information about type-checking options, and about improvements to template type checking in version 9 and above, see [Template type checking](guide/template-typecheck).
|
|
||||||
|
|
||||||
</div>
|
|
||||||
|
|
||||||
Template validation produces error messages when a type error is detected in a template binding
|
|
||||||
expression, similar to how type errors are reported by the TypeScript compiler against code in a `.ts`
|
|
||||||
file.
|
|
||||||
|
|
||||||
For example, consider the following component:
|
|
||||||
|
|
||||||
```typescript
|
|
||||||
@Component({
|
|
||||||
selector: 'my-component',
|
|
||||||
template: '{{person.addresss.street}}'
|
|
||||||
})
|
|
||||||
class MyComponent {
|
|
||||||
person?: Person;
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
This produces the following error:
|
|
||||||
|
|
||||||
```
|
|
||||||
my.component.ts.MyComponent.html(1,1): : Property 'addresss' does not exist on type 'Person'. Did you mean 'address'?
|
|
||||||
```
|
|
||||||
|
|
||||||
The file name reported in the error message, `my.component.ts.MyComponent.html`, is a synthetic file
|
|
||||||
generated by the template compiler that holds contents of the `MyComponent` class template.
|
|
||||||
The compiler never writes this file to disk.
|
|
||||||
The line and column numbers are relative to the template string in the `@Component` annotation of the class, `MyComponent` in this case.
|
|
||||||
If a component uses `templateUrl` instead of `template`, the errors are reported in the HTML file referenced by the `templateUrl` instead of a synthetic file.
|
|
||||||
|
|
||||||
The error location is the beginning of the text node that contains the interpolation expression with the error.
|
|
||||||
If the error is in an attribute binding such as `[value]="person.address.street"`, the error
|
|
||||||
location is the location of the attribute that contains the error.
|
|
||||||
|
|
||||||
The validation uses the TypeScript type checker and the options supplied to the TypeScript compiler to control how detailed the type validation is.
|
|
||||||
For example, if the `strictTypeChecks` is specified, the error
|
|
||||||
```my.component.ts.MyComponent.html(1,1): : Object is possibly 'undefined'```
|
|
||||||
is reported as well as the above error message.
|
|
||||||
|
|
||||||
### Type narrowing
|
|
||||||
|
|
||||||
The expression used in an `ngIf` directive is used to narrow type unions in the Angular
|
|
||||||
template compiler, the same way the `if` expression does in TypeScript.
|
|
||||||
For example, to avoid `Object is possibly 'undefined'` error in the template above, modify it to only emit the interpolation if the value of `person` is initialized as shown below:
|
|
||||||
|
|
||||||
```typescript
|
|
||||||
@Component({
|
|
||||||
selector: 'my-component',
|
|
||||||
template: '<span *ngIf="person"> {{person.addresss.street}} </span>'
|
|
||||||
})
|
|
||||||
class MyComponent {
|
|
||||||
person?: Person;
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
Using `*ngIf` allows the TypeScript compiler to infer that the `person` used in the binding expression will never be `undefined`.
|
|
||||||
|
|
||||||
For more information about input type narrowing, see [Input setter coercion](guide/template-typecheck#input-setter-coercion) and [Improving template type checking for custom directives](guide/structural-directives#directive-type-checks).
|
|
||||||
|
|
||||||
### Non-null type assertion operator
|
|
||||||
|
|
||||||
Use the [non-null type assertion operator](guide/template-expression-operators#non-null-assertion-operator) to suppress the `Object is possibly 'undefined'` error when it is inconvenient to use `*ngIf` or when some constraint in the component ensures that the expression is always non-null when the binding expression is interpolated.
|
|
||||||
|
|
||||||
In the following example, the `person` and `address` properties are always set together, implying that `address` is always non-null if `person` is non-null.
|
|
||||||
There is no convenient way to describe this constraint to TypeScript and the template compiler, but the error is suppressed in the example by using `address!.street`.
|
|
||||||
|
|
||||||
```typescript
|
|
||||||
@Component({
|
|
||||||
selector: 'my-component',
|
|
||||||
template: '<span *ngIf="person"> {{person.name}} lives on {{address!.street}} </span>'
|
|
||||||
})
|
|
||||||
class MyComponent {
|
|
||||||
person?: Person;
|
|
||||||
address?: Address;
|
|
||||||
|
|
||||||
setData(person: Person, address: Address) {
|
|
||||||
this.person = person;
|
|
||||||
this.address = address;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
The non-null assertion operator should be used sparingly as refactoring of the component might break this constraint.
|
|
||||||
|
|
||||||
In this example it is recommended to include the checking of `address` in the `*ngIf` as shown below:
|
|
||||||
|
|
||||||
```typescript
|
|
||||||
@Component({
|
|
||||||
selector: 'my-component',
|
|
||||||
template: '<span *ngIf="person && address"> {{person.name}} lives on {{address.street}} </span>'
|
|
||||||
})
|
|
||||||
class MyComponent {
|
|
||||||
person?: Person;
|
|
||||||
address?: Address;
|
|
||||||
|
|
||||||
setData(person: Person, address: Address) {
|
|
||||||
this.person = person;
|
|
||||||
this.address = address;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
@ -1,59 +1,62 @@
|
|||||||
# Compilación anticipada (AOT)
|
# Ahead-of-time (AOT) compilation
|
||||||
|
|
||||||
Una aplicación Angular consta principalmente de componentes y sus plantillas HTML. Los componentes y plantillas proporcionados por Angular no pueden ser entendidos por el navegador directamente, las aplicaciones en Angular requieren un proceso de compilación antes de que puedan correr en un navegador.
|
An Angular application consists mainly of components and their HTML templates. Because the components and templates provided by Angular cannot be understood by the browser directly, Angular applications require a compilation process before they can run in a browser.
|
||||||
|
|
||||||
La [compilación anticipada de Angular (AOT)](guide/glossary#aot) convierte plantillas y código de TypeScript en eficiente código JavaScript durante la fase de construcción _antes_ de que el navegador descargue y corra el código. Compilando tu aplicación durante el proceso de construcción se proporciona una renderización más rápida en el navegador.
|
The Angular [ahead-of-time (AOT) compiler](guide/glossary#aot) converts your Angular HTML and TypeScript code into efficient JavaScript code during the build phase _before_ the browser downloads and runs that code. Compiling your application during the build process provides a faster rendering in the browser.
|
||||||
|
|
||||||
Esta guía explica como especificar metadatos y aplicar las opciones del compilador disponibles para compilar aplicaciones eficientemente usando la compilación anticipada (AOT).
|
This guide explains how to specify metadata and apply available compiler options to compile your applications efficiently using the AOT compiler.
|
||||||
|
|
||||||
<div class="alert is-helpful">
|
<div class="alert is-helpful">
|
||||||
|
|
||||||
<a href="https://www.youtube.com/watch?v=anphffaCZrQ">Mira a Alex Rickabaugh explicando el compilador de Angular en AngularConnect 2019.
|
<a href="https://www.youtube.com/watch?v=anphffaCZrQ">Watch Alex Rickabaugh explain the Angular compiler</a> at AngularConnect 2019.
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{@a why-aot}
|
{@a why-aot}
|
||||||
|
|
||||||
Aquí algunas razones por las qué podrías querer usar AOT.
|
Here are some reasons you might want to use AOT.
|
||||||
|
|
||||||
* *Renderizado más rápido*
|
* *Faster rendering*
|
||||||
Con AOT, el navegador descarga una versión pre compilada de una aplicación.
|
With AOT, the browser downloads a pre-compiled version of the application.
|
||||||
El navegador carga el código ejecutable para que pueda renderizar la aplicación inmediatamente, sin esperar a compilar la aplicación primero.
|
The browser loads executable code so it can render the application immediately, without waiting to compile the app first.
|
||||||
|
|
||||||
* *Menos solicitudes asincrónicas*
|
* *Fewer asynchronous requests*
|
||||||
El compilador _inserta_ plantillas HTML y hojas de estilo CSS externas dentro de la aplicación JavaScript, eliminando solicitudes ajax separadas para esos archivos fuente.
|
The compiler _inlines_ external HTML templates and CSS style sheets within the application JavaScript,
|
||||||
|
eliminating separate ajax requests for those source files.
|
||||||
|
|
||||||
* *Angular pesa menos*
|
* *Smaller Angular framework download size*
|
||||||
No existe necesidad de incluir el compilador de Angular si la aplicación ya esta compilada.
|
There's no need to download the Angular compiler if the app is already compiled.
|
||||||
El compilador es aproximadamente la mitad de Angular en si mismo, así que omitíendolo se reduce drásticamente el peso de la aplicación.
|
The compiler is roughly half of Angular itself, so omitting it dramatically reduces the application payload.
|
||||||
|
|
||||||
* *Detecte errores en platillas antes*
|
* *Detect template errors earlier*
|
||||||
El compilador AOT detecta y reporta errores de enlace de datos en plantillas durante el paso de construcción antes que los usuarios puedan verlos.
|
The AOT compiler detects and reports template binding errors during the build step
|
||||||
|
before users can see them.
|
||||||
|
|
||||||
* *Mejor seguridad*
|
* *Better security*
|
||||||
AOT compila las plantillas HTML y componentes en archivos JavaScript mucho antes de que se sirvan a el cliente.
|
AOT compiles HTML templates and components into JavaScript files long before they are served to the client.
|
||||||
Sin plantillas para leer y sin evaluaciones de JavaScript o HTML del lado del cliente riesgosas, existen pocas oportunidades para ataques de inyección.
|
With no templates to read and no risky client-side HTML or JavaScript evaluation,
|
||||||
|
there are fewer opportunities for injection attacks.
|
||||||
|
|
||||||
{@a overview}
|
{@a overview}
|
||||||
|
|
||||||
## Eligiendo un compilador.
|
## Choosing a compiler
|
||||||
|
|
||||||
Angular ofrece dos formas para compilar tu aplicación:
|
Angular offers two ways to compile your application:
|
||||||
|
|
||||||
* **_Just-in-Time_ (JIT)**, cuando compila tu aplicación en el navegador en tiempo de ejecución. Este fué el modo de compilación por defecto hasta Angular 8.
|
* **_Just-in-Time_ (JIT)**, which compiles your app in the browser at runtime. This was the default until Angular 8.
|
||||||
* **_Ahead-of-Time_ (AOT)**, cuando compila tu aplicación y librerías en el tiempo de construcción. Este es el modo de compilación por defecto desde Angular 9.
|
* **_Ahead-of-Time_ (AOT)**, which compiles your app and libraries at build time. This is the default since Angular 9.
|
||||||
|
|
||||||
Cuando ejecutas los comandos del CLI [`ng build`](cli/build) (solo construcción) o [`ng serve`](cli/serve) (construye y sirve localmente), el tipo de compilación (JIT o AOT) depende del valor de la propiedad `aot` en tu configuración de construcción especificada en el archivo `angular.json`. Por defecto, `aot` esta establecido en `true` para nuevas aplicaciones.
|
When you run the [`ng build`](cli/build) (build only) or [`ng serve`](cli/serve) (build and serve locally) CLI commands, the type of compilation (JIT or AOT) depends on the value of the `aot` property in your build configuration specified in `angular.json`. By default, `aot` is set to `true` for new CLI apps.
|
||||||
|
|
||||||
Mira la [referencia de comandos del CLI](cli) y [Construyendo y sirviendo Angular apps](guide/build) para más información.
|
See the [CLI command reference](cli) and [Building and serving Angular apps](guide/build) for more information.
|
||||||
|
|
||||||
## Como funciona AOT
|
## How AOT works
|
||||||
|
|
||||||
El compilador de Angular AOT extrae **metadatos** para interpretar las partes de la aplicación que se supone que Angular maneja.
|
The Angular AOT compiler extracts **metadata** to interpret the parts of the application that Angular is supposed to manage.
|
||||||
Puedes especificar los metadatos explícitamente en **decoradores** como `@Component()` y `@Input()`, o implícitamente en las declaraciones del constructor de las clases decoradas.
|
You can specify the metadata explicitly in **decorators** such as `@Component()` and `@Input()`, or implicitly in the constructor declarations of the decorated classes.
|
||||||
Los metadatos le dicen a Angular como construir instancias de clases e interactuar con ellas en tiempo de ejecución.
|
The metadata tells Angular how to construct instances of your application classes and interact with them at runtime.
|
||||||
|
|
||||||
En el siguiente ejemplo, los metadatos de `@Component()` y el constructor le dicen a Angular como crear y mostrar una instancia de `TypicalComponent`.
|
In the following example, the `@Component()` metadata object and the class constructor tell Angular how to create and display an instance of `TypicalComponent`.
|
||||||
|
|
||||||
```typescript
|
```typescript
|
||||||
@Component({
|
@Component({
|
||||||
@ -66,63 +69,63 @@ export class TypicalComponent {
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
El compilador de Angular extrae los metadatos _una_ vez y genera una _fabrica_ para `TypicalComponent`.
|
The Angular compiler extracts the metadata _once_ and generates a _factory_ for `TypicalComponent`.
|
||||||
Cuando este necesita crear una instancia de `TypicalComponent`, Angular llama a la fabrica, el cuál produce un nuevo elemento visual, vinculado a una nueva instancia la clase del componente con su dependencia inyectada.
|
When it needs to create a `TypicalComponent` instance, Angular calls the factory, which produces a new visual element, bound to a new instance of the component class with its injected dependency.
|
||||||
|
|
||||||
### Fases de compilación
|
### Compilation phases
|
||||||
|
|
||||||
Existen tres fases de compilación en AOT.
|
There are three phases of AOT compilation.
|
||||||
|
* Phase 1 is *code analysis*.
|
||||||
|
In this phase, the TypeScript compiler and *AOT collector* create a representation of the source. The collector does not attempt to interpret the metadata it collects. It represents the metadata as best it can and records errors when it detects a metadata syntax violation.
|
||||||
|
|
||||||
* Fase 1: *análisis de código*
|
* Phase 2 is *code generation*.
|
||||||
En esta fase, el compilador de TypeScript y el *recolector AOT* crea una representación de la fuente. El recolector no intenta interpretar los metadatos recopilados. Estos representan los metadatos lo mejor que pueden y registra errores cuando este detecta un violación de sintaxis en los metadatos.
|
In this phase, the compiler's `StaticReflector` interprets the metadata collected in phase 1, performs additional validation of the metadata, and throws an error if it detects a metadata restriction violation.
|
||||||
|
|
||||||
* Fase 2: *generación de código*
|
* Phase 3 is *template type checking*.
|
||||||
En esta fase, el `StaticReflector` del compilador interpreta los metadatos recolectados en la fase 1, realiza validaciones adicionales de los metadatos y lanza un error si este detecta una violación de la restricción de metadatos.
|
In this optional phase, the Angular *template compiler* uses the TypeScript compiler to validate the binding expressions in templates. You can enable this phase explicitly by setting the `fullTemplateTypeCheck` configuration option; see [Angular compiler options](guide/angular-compiler-options).
|
||||||
|
|
||||||
* Fase 3: *verificación de tipos en plantillas*
|
|
||||||
Esta fase es opcional, el *compilador de plantillas* de Angular usa el compilador de Typescript para validar las expresiones de enlaces de datos en las plantillas. Puedes habilitar esta fase explícitamente configurando la opción `fullTemplateTypeCheck`; revisa [Opciones del Compilador Angular](guide/angular-compiler-options).
|
|
||||||
|
|
||||||
|
|
||||||
### Restricciones de los metadatos
|
### Metadata restrictions
|
||||||
|
|
||||||
Escribe metadatos en un _subconjunto_ de TypeScript que debe cumplir las siguientes restricciones generales:
|
You write metadata in a _subset_ of TypeScript that must conform to the following general constraints:
|
||||||
|
|
||||||
* Limita la [sintaxis de expresiones](#expression-syntax) al subconjunto soportado de JavaScript.
|
* Limit [expression syntax](#expression-syntax) to the supported subset of JavaScript.
|
||||||
* Solo haz referencia a los símbolos exportados después del [plegado de código](#code-folding).
|
* Only reference exported symbols after [code folding](#code-folding).
|
||||||
* Solo llame [funciones compátibles](#supported-functions) por el compilador.
|
* Only call [functions supported](#supported-functions) by the compiler.
|
||||||
* Miembros de clase decorados y con enlaces de datos deben ser públicos.
|
* Decorated and data-bound class members must be public.
|
||||||
|
|
||||||
Para guías e instrucciones adicionales al preparar una aplicación para compilación anticipada (AOT), revise [Angular: Writing AOT-friendly applications](https://medium.com/sparkles-blog/angular-writing-aot-friendly-applications-7b64c8afbe3f).
|
For additional guidelines and instructions on preparing an application for AOT compilation, see [Angular: Writing AOT-friendly applications](https://medium.com/sparkles-blog/angular-writing-aot-friendly-applications-7b64c8afbe3f).
|
||||||
|
|
||||||
<div class="alert is-helpful">
|
<div class="alert is-helpful">
|
||||||
|
|
||||||
Los errores en compilación anticipada (AOT) comúnmente ocurren debido a que los metadatos no se ajustan a los requisitos del compilador (como se describen con más detalle a continuación).
|
Errors in AOT compilation commonly occur because of metadata that does not conform to the compiler's requirements (as described more fully below).
|
||||||
Para ayudar a entender y resolver estos problemas, revisa [Errores de metadatos en AOT](guide/aot-metadata-errors).
|
For help in understanding and resolving these problems, see [AOT Metadata Errors](guide/aot-metadata-errors).
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
### Configurando la compilación anticipada (AOT).
|
### Configuring AOT compilation
|
||||||
|
|
||||||
Puedes proporcionar opciones en el [archivo de configuración de TypeScript](guide/typescript-configuration) que controlan el proceso de compilación. Revisa [las opciones de compilación de Angular](guide/angular-compiler-options) para una lista completa de opciones disponibles.
|
You can provide options in the [TypeScript configuration file](guide/typescript-configuration) that controls the compilation process. See [Angular compiler options](guide/angular-compiler-options) for a complete list of available options.
|
||||||
|
|
||||||
## Fase 1: Análisis de código.
|
## Phase 1: Code analysis
|
||||||
|
|
||||||
El compilador de TypeScript realiza parte del trabajo analítico en la primer fase. Este emite los _archivos de definición de tipos_ `.d.ts` con el tipo de información que el compilador AOT necesita para generar el código de la aplicación.
|
The TypeScript compiler does some of the analytic work of the first phase. It emits the `.d.ts` _type definition files_ with type information that the AOT compiler needs to generate application code.
|
||||||
Al mismo tiempo, el **recolector** AOT analiza los metadatos registrados en los decoradores de Angular y genera información de metadatos en archivos **`.metadata.json`**, uno por archivo `.d.ts`.
|
At the same time, the AOT **collector** analyzes the metadata recorded in the Angular decorators and outputs metadata information in **`.metadata.json`** files, one per `.d.ts` file.
|
||||||
|
|
||||||
Puedes pensar en `.metadata.json` como un diagrama de la estructura general de los metadatos de un decorador, representados como un [árbol de sintaxis abstracta (AST)](https://en.wikipedia.org/wiki/Abstract_syntax_tree).
|
You can think of `.metadata.json` as a diagram of the overall structure of a decorator's metadata, represented as an [abstract syntax tree (AST)](https://en.wikipedia.org/wiki/Abstract_syntax_tree).
|
||||||
|
|
||||||
<div class="alert is-helpful">
|
<div class="alert is-helpful">
|
||||||
|
|
||||||
El [schema.ts](https://github.com/angular/angular/blob/master/packages/compiler-cli/src/metadata/schema.ts) de Angular describe el formato JSON como una colección de interfaces de TypeScript.
|
Angular's [schema.ts](https://github.com/angular/angular/blob/master/packages/compiler-cli/src/metadata/schema.ts)
|
||||||
|
describes the JSON format as a collection of TypeScript interfaces.
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{@a expression-syntax}
|
{@a expression-syntax}
|
||||||
### Limitaciones del sintaxis de expresión.
|
### Expression syntax limitations
|
||||||
|
|
||||||
El recolector de AOT solo entiende un subconjunto de JavaScript.
|
The AOT collector only understands a subset of JavaScript.
|
||||||
Defina objetos de metadatos con la siguiente sintaxis limitada:
|
Define metadata objects with the following limited syntax:
|
||||||
|
|
||||||
<style>
|
<style>
|
||||||
td, th {vertical-align: top}
|
td, th {vertical-align: top}
|
||||||
@ -130,84 +133,85 @@ Defina objetos de metadatos con la siguiente sintaxis limitada:
|
|||||||
|
|
||||||
<table>
|
<table>
|
||||||
<tr>
|
<tr>
|
||||||
<th>Sintaxis</th>
|
<th>Syntax</th>
|
||||||
<th>Ejemplo</th>
|
<th>Example</th>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td>Objeto literal </td>
|
<td>Literal object </td>
|
||||||
<td><code>{cherry: true, apple: true, mincemeat: false}</code></td>
|
<td><code>{cherry: true, apple: true, mincemeat: false}</code></td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td>Colección literal </td>
|
<td>Literal array </td>
|
||||||
<td><code>['cherries', 'flour', 'sugar']</code></td>
|
<td><code>['cherries', 'flour', 'sugar']</code></td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td>Operador spread en colección literal</td>
|
<td>Spread in literal array</td>
|
||||||
<td><code>['apples', 'flour', ...the_rest]</code></td>
|
<td><code>['apples', 'flour', ...the_rest]</code></td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td>Llamadas</td>
|
<td>Calls</td>
|
||||||
<td><code>bake(ingredients)</code></td>
|
<td><code>bake(ingredients)</code></td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td>Nuevo</td>
|
<td>New</td>
|
||||||
<td><code>new Oven()</code></td>
|
<td><code>new Oven()</code></td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td>Acceso a propiedades</td>
|
<td>Property access</td>
|
||||||
<td><code>pie.slice</code></td>
|
<td><code>pie.slice</code></td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td>Indices de colección</td>
|
<td>Array index</td>
|
||||||
<td><code>ingredients[0]</code></td>
|
<td><code>ingredients[0]</code></td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td>Referencia de identidad</td>
|
<td>Identity reference</td>
|
||||||
<td><code>Component</code></td>
|
<td><code>Component</code></td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td>Una plantilla de cadena</td>
|
<td>A template string</td>
|
||||||
<td><code>`pie is ${multiplier} times better than cake`</code></td>
|
<td><code>`pie is ${multiplier} times better than cake`</code></td>
|
||||||
<tr>
|
<tr>
|
||||||
<td>Cadena literal</td>
|
<td>Literal string</td>
|
||||||
<td><code>pi</code></td>
|
<td><code>pi</code></td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td>Numero literal</td>
|
<td>Literal number</td>
|
||||||
<td><code>3.14153265</code></td>
|
<td><code>3.14153265</code></td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td>Booleano literal</td>
|
<td>Literal boolean</td>
|
||||||
<td><code>true</code></td>
|
<td><code>true</code></td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td>Nulo literal</td>
|
<td>Literal null</td>
|
||||||
<td><code>null</code></td>
|
<td><code>null</code></td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td>Soporte a operador prefijo</td>
|
<td>Supported prefix operator </td>
|
||||||
<td><code>!cake</code></td>
|
<td><code>!cake</code></td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td>Soporte a operaciones binarias</td>
|
<td>Supported binary operator </td>
|
||||||
<td><code>a+b</code></td>
|
<td><code>a+b</code></td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td>Operador condicional</td>
|
<td>Conditional operator</td>
|
||||||
<td><code>a ? b : c</code></td>
|
<td><code>a ? b : c</code></td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td>Paréntesis</td>
|
<td>Parentheses</td>
|
||||||
<td><code>(a+b)</code></td>
|
<td><code>(a+b)</code></td>
|
||||||
</tr>
|
</tr>
|
||||||
</table>
|
</table>
|
||||||
|
|
||||||
Si una expresión usa sintaxis no compatible, el recolector escribe un error de nodo en el archivo `.metadata.json`.
|
|
||||||
El compilador luego reporta el error si necesita esa pieza de metadatos para generar el código de la aplicación.
|
If an expression uses unsupported syntax, the collector writes an error node to the `.metadata.json` file.
|
||||||
|
The compiler later reports the error if it needs that piece of metadata to generate the application code.
|
||||||
|
|
||||||
<div class="alert is-helpful">
|
<div class="alert is-helpful">
|
||||||
|
|
||||||
Si quieres que `ngc` reporte errores de sintaxis inmediatamente en lugar de producir un archivo `.metadata.json` con errores, configurá la opción `strictMetadataEmit` en el archivo de configuración de TypeScript.
|
If you want `ngc` to report syntax errors immediately rather than produce a `.metadata.json` file with errors, set the `strictMetadataEmit` option in the TypeScript configuration file.
|
||||||
|
|
||||||
```
|
```
|
||||||
"angularCompilerOptions": {
|
"angularCompilerOptions": {
|
||||||
@ -216,17 +220,18 @@ El compilador luego reporta el error si necesita esa pieza de metadatos para gen
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
Las librerías de Angular tienen esta opción para asegurar que todo los archivos `.metadata.json` están limpios y es una buena practica hacer lo mismo cuando construimos nuestras propias librerías.
|
Angular libraries have this option to ensure that all Angular `.metadata.json` files are clean and it is a best practice to do the same when building your own libraries.
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{@a function-expression}
|
{@a function-expression}
|
||||||
{@a arrow-functions}
|
{@a arrow-functions}
|
||||||
### Sin funciones flecha
|
### No arrow functions
|
||||||
|
|
||||||
El compilador AOT no soporta [expresiones de función](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/function) y [funciones flecha](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/function), tampoco las funciones llamadas _lambda_.
|
The AOT compiler does not support [function expressions](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/function)
|
||||||
|
and [arrow functions](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/Arrow_functions), also called _lambda_ functions.
|
||||||
|
|
||||||
Considere el siguiente decorador del componente:
|
Consider the following component decorator:
|
||||||
|
|
||||||
```typescript
|
```typescript
|
||||||
@Component({
|
@Component({
|
||||||
@ -235,11 +240,11 @@ Considere el siguiente decorador del componente:
|
|||||||
})
|
})
|
||||||
```
|
```
|
||||||
|
|
||||||
El recolector de AOT no soporta la función tipo flecha, `() => new Server()`, en una expression de los metadatos.
|
The AOT collector does not support the arrow function, `() => new Server()`, in a metadata expression.
|
||||||
Esto genera un error de nodo en lugar de la función.
|
It generates an error node in place of the function.
|
||||||
Cuando el compilador posteriormente interpreta este nodo, este reporta un error que invita a convertir la función flecha en una _función exportada_.
|
When the compiler later interprets this node, it reports an error that invites you to turn the arrow function into an _exported function_.
|
||||||
|
|
||||||
Puedes arreglar este error convirtiendo a esto:
|
You can fix the error by converting to this:
|
||||||
|
|
||||||
```typescript
|
```typescript
|
||||||
export function serverFactory() {
|
export function serverFactory() {
|
||||||
@ -252,23 +257,23 @@ export function serverFactory() {
|
|||||||
})
|
})
|
||||||
```
|
```
|
||||||
|
|
||||||
En la version 5 y posterior, el compilador realiza automáticamente esta re escritura mientras emite el archivo `.js`.
|
In version 5 and later, the compiler automatically performs this rewriting while emitting the `.js` file.
|
||||||
|
|
||||||
{@a exported-symbols}
|
{@a exported-symbols}
|
||||||
{@a code-folding}
|
{@a code-folding}
|
||||||
### Plegado de código (code folding)
|
### Code folding
|
||||||
|
|
||||||
El compilador puede solo resolver referencias a símbolos **_exportados_**.
|
The compiler can only resolve references to **_exported_** symbols.
|
||||||
El recolector sin embargo, puede evaluar una expresión durante la recolección y registrar el resultado en el `.metadata.json`, en vez de la expresión original.
|
The collector, however, can evaluate an expression during collection and record the result in the `.metadata.json`, rather than the original expression.
|
||||||
Esto permite hacer un uso limitado de símbolos no exportados dentro de expresiones.
|
This allows you to make limited use of non-exported symbols within expressions.
|
||||||
|
|
||||||
Por ejemplo, el recolector puede evaluar la expresión `1 + 2 + 3 + 4` y remplazarlo con el resultado, `10`.
|
For example, the collector can evaluate the expression `1 + 2 + 3 + 4` and replace it with the result, `10`.
|
||||||
El proceso es llamado _plegado_. Una expresión que puede se reducida de esta manera es _plegable_.
|
This process is called _folding_. An expression that can be reduced in this manner is _foldable_.
|
||||||
|
|
||||||
{@a var-declaration}
|
{@a var-declaration}
|
||||||
El recolector puede evaluar referencias hacia el modulo local, declaraciones `const` e inicializadas en `var` y `let` efectivamente son removidas del archivo `.metadata.json`.
|
The collector can evaluate references to module-local `const` declarations and initialized `var` and `let` declarations, effectively removing them from the `.metadata.json` file.
|
||||||
|
|
||||||
Considere la siguiente definición del componente:
|
Consider the following component definition:
|
||||||
|
|
||||||
```typescript
|
```typescript
|
||||||
const template = '<div>{{hero.name}}</div>';
|
const template = '<div>{{hero.name}}</div>';
|
||||||
@ -282,9 +287,9 @@ export class HeroComponent {
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
El compilador no podría referirse hacia la constante `template` por que esta no ha sido exportada.
|
The compiler could not refer to the `template` constant because it isn't exported.
|
||||||
El recolector sim embargo, puede encontrar la constante `template` dentro de la definición de metadatos insertando su contenido.
|
The collector, however, can fold the `template` constant into the metadata definition by in-lining its contents.
|
||||||
El efecto es el mismo como si hubieras escrito:
|
The effect is the same as if you had written:
|
||||||
|
|
||||||
```typescript
|
```typescript
|
||||||
@Component({
|
@Component({
|
||||||
@ -296,9 +301,9 @@ export class HeroComponent {
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
No hay una referencia a `template` y por lo tanto nada que moleste al compilador cuando posteriormente interprete las salidas del recolector en el archivo `.metadata.json`.
|
There is no longer a reference to `template` and, therefore, nothing to trouble the compiler when it later interprets the _collector's_ output in `.metadata.json`.
|
||||||
|
|
||||||
Puedes tomar este ejemplo un paso más allá para incluir la constante `template` en otra expresión:
|
You can take this example a step further by including the `template` constant in another expression:
|
||||||
|
|
||||||
```typescript
|
```typescript
|
||||||
const template = '<div>{{hero.name}}</div>';
|
const template = '<div>{{hero.name}}</div>';
|
||||||
@ -312,15 +317,15 @@ export class HeroComponent {
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
El recolector reduce esta expresión a su equivalente cadena _plegada_:
|
The collector reduces this expression to its equivalent _folded_ string:
|
||||||
|
|
||||||
```
|
```
|
||||||
'<div>{{hero.name}}</div><div>{{hero.title}}</div>'
|
'<div>{{hero.name}}</div><div>{{hero.title}}</div>'
|
||||||
```
|
```
|
||||||
|
|
||||||
#### Sintaxis plegable
|
#### Foldable syntax
|
||||||
|
|
||||||
La siguiente tabla describe cuales expresiones el recolector puede y no puede encontrar:
|
The following table describes which expressions the collector can and cannot fold:
|
||||||
|
|
||||||
<style>
|
<style>
|
||||||
td, th {vertical-align: top}
|
td, th {vertical-align: top}
|
||||||
@ -328,101 +333,101 @@ La siguiente tabla describe cuales expresiones el recolector puede y no puede en
|
|||||||
|
|
||||||
<table>
|
<table>
|
||||||
<tr>
|
<tr>
|
||||||
<th>Sintaxis</th>
|
<th>Syntax</th>
|
||||||
<th>Plegable</th>
|
<th>Foldable</th>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td>Objeto literal </td>
|
<td>Literal object </td>
|
||||||
<td>si</td>
|
<td>yes</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td>Colección literal </td>
|
<td>Literal array </td>
|
||||||
<td>si</td>
|
<td>yes</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td>Operador spread en colección literal</td>
|
<td>Spread in literal array</td>
|
||||||
<td>no</td>
|
<td>no</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td>Llamadas</td>
|
<td>Calls</td>
|
||||||
<td>no</td>
|
<td>no</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td>Nuevo</td>
|
<td>New</td>
|
||||||
<td>no</td>
|
<td>no</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td>Acceso a propiedades<</td>
|
<td>Property access</td>
|
||||||
<td>si, si el objetivo es plegable</td>
|
<td>yes, if target is foldable</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td>Indices de colección</td>
|
<td>Array index</td>
|
||||||
<td>si, si el objetivo y el indice es plegable</td>
|
<td> yes, if target and index are foldable</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td>Referencia de identidad</td>
|
<td>Identity reference</td>
|
||||||
<td>si, si es una referencia a una local</td>
|
<td>yes, if it is a reference to a local</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td>Una plantilla sin sustituciones</td>
|
<td>A template with no substitutions</td>
|
||||||
<td>si</td>
|
<td>yes</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td>Una plantilla con sustituciones</td>
|
<td>A template with substitutions</td>
|
||||||
<td>si, si las sustituciones son plegables</td>
|
<td>yes, if the substitutions are foldable</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td>Cadena literal</td>
|
<td>Literal string</td>
|
||||||
<td>si</td>
|
<td>yes</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td>Numero literal</td>
|
<td>Literal number</td>
|
||||||
<td>si</td>
|
<td>yes</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td>Booleano literal</td>
|
<td>Literal boolean</td>
|
||||||
<td>si</td>
|
<td>yes</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td>Nulo literal</td>
|
<td>Literal null</td>
|
||||||
<td>si</td>
|
<td>yes</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td>Soporte a operador prefijo </td>
|
<td>Supported prefix operator </td>
|
||||||
<td>si, si el operador es plegable</td>
|
<td>yes, if operand is foldable</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td>Soporte a operador binario </td>
|
<td>Supported binary operator </td>
|
||||||
<td>si, si ambos tanto el izquierda y derecha con plegables</td>
|
<td>yes, if both left and right are foldable</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td>Operador condicional</td>
|
<td>Conditional operator</td>
|
||||||
<td>si, si la condición es plegable </td>
|
<td>yes, if condition is foldable </td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td>Paréntesis</td>
|
<td>Parentheses</td>
|
||||||
<td>si, si la expresión es plegable</td>
|
<td>yes, if the expression is foldable</td>
|
||||||
</tr>
|
</tr>
|
||||||
</table>
|
</table>
|
||||||
|
|
||||||
|
|
||||||
Si es una expresión no plegable, el recolector lo escribe a `.metadata.json` como un [AST](https://en.wikipedia.org/wiki/Abstract_syntax_tree) para que el compilador lo resuelva.
|
If an expression is not foldable, the collector writes it to `.metadata.json` as an [AST](https://en.wikipedia.org/wiki/Abstract_syntax_tree) for the compiler to resolve.
|
||||||
|
|
||||||
|
|
||||||
## Fase 2: generación de código
|
## Phase 2: code generation
|
||||||
|
|
||||||
El recolector no hace ningún intento para entender los metadatos que se recolectarón y las envía a `.metadata.json`.
|
The collector makes no attempt to understand the metadata that it collects and outputs to `.metadata.json`.
|
||||||
Esto representa los metadatos lo mejor que puede y registra errores cuando detecta una violación de sintaxis en los metadatos.
|
It represents the metadata as best it can and records errors when it detects a metadata syntax violation.
|
||||||
Es el trabajo del compilador interpretar el `.metadata.json` en la fase de generación de código.
|
It's the compiler's job to interpret the `.metadata.json` in the code generation phase.
|
||||||
|
|
||||||
El compilador entiende toda las formas de sintaxis que el recolector soporta pero puede rechazar metadatos _sintácticamente_ correctos si la _semántica_ viola reglas del compilador.
|
The compiler understands all syntax forms that the collector supports, but it may reject _syntactically_ correct metadata if the _semantics_ violate compiler rules.
|
||||||
|
|
||||||
### Símbolos públicos
|
### Public symbols
|
||||||
|
|
||||||
El compilador puede solo referirse a _símbolos exportados_.
|
The compiler can only reference _exported symbols_.
|
||||||
|
|
||||||
* Los atributos de la clase que tienen un decorador deben ser públicos. No puedes hacer que una propiedad `@Input()` sea privada o protegida.
|
* Decorated component class members must be public. You cannot make an `@Input()` property private or protected.
|
||||||
* Las propiedades enlazadas a datos también deben ser publicas.
|
* Data bound properties must also be public.
|
||||||
|
|
||||||
```typescript
|
```typescript
|
||||||
// BAD CODE - title is private
|
// BAD CODE - title is private
|
||||||
@ -437,32 +442,32 @@ export class AppComponent {
|
|||||||
|
|
||||||
{@a supported-functions}
|
{@a supported-functions}
|
||||||
|
|
||||||
### Clases y funciones compatibles
|
### Supported classes and functions
|
||||||
|
|
||||||
El recolector puede representar una función o la creación de un objeto con `new` mientras la sintaxis sea valida.
|
The collector can represent a function call or object creation with `new` as long as the syntax is valid.
|
||||||
El compilador, sin embargo, puede posteriormente rechazar a generar una llamada hacia una función _particular_ o la creación de un objeto _particular_.
|
The compiler, however, can later refuse to generate a call to a _particular_ function or creation of a _particular_ object.
|
||||||
|
|
||||||
El compilador puede solo crea instancias de ciertas clases, compatibles solo con decoradores centrales y solo compatibles con llamadas a macros (funciones o métodos estáticos) que retornan expresiones.
|
The compiler can only create instances of certain classes, supports only core decorators, and only supports calls to macros (functions or static methods) that return expressions.
|
||||||
|
* New instances
|
||||||
|
|
||||||
* Nuevas instancias
|
The compiler only allows metadata that create instances of the class `InjectionToken` from `@angular/core`.
|
||||||
El compilador solo permite metadatos que crean instancias de las clases `InjectionToken` de `@angular/core`.
|
|
||||||
|
|
||||||
* Decoradores soportados
|
* Supported decorators
|
||||||
El compilador solo soporta metadatos del [Modulo de decoradores de Angular en `@angular/core`](api/core#decorators).
|
|
||||||
|
|
||||||
* Llamadas a funciones
|
The compiler only supports metadata for the [Angular decorators in the `@angular/core` module](api/core#decorators).
|
||||||
|
|
||||||
Las funciones de fabrica deben ser exportadas.
|
* Function calls
|
||||||
El compilador AOT no soporta expresiones lambda ("funciones flecha") para las funciones de fabrica.
|
|
||||||
|
Factory functions must be exported, named functions.
|
||||||
|
The AOT compiler does not support lambda expressions ("arrow functions") for factory functions.
|
||||||
|
|
||||||
{@a function-calls}
|
{@a function-calls}
|
||||||
|
### Functions and static method calls
|
||||||
|
|
||||||
### Llamadas a funciones y métodos estáticos.
|
The collector accepts any function or static method that contains a single `return` statement.
|
||||||
|
The compiler, however, only supports macros in the form of functions or static methods that return an *expression*.
|
||||||
|
|
||||||
El recolector acepta cualquier función o método estático que contenga una sola declaración de `return`.
|
For example, consider the following function:
|
||||||
El compilador sin embargo, solo soporta macros (funciones o métodos estáticos) en la forma de funciones y métodos estáticos que retornan una *expression*.
|
|
||||||
|
|
||||||
Por ejemplo, considere la siguiente función:
|
|
||||||
|
|
||||||
```typescript
|
```typescript
|
||||||
export function wrapInArray<T>(value: T): T[] {
|
export function wrapInArray<T>(value: T): T[] {
|
||||||
@ -470,9 +475,9 @@ export function wrapInArray<T>(value: T): T[] {
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
Puedes llamar a `wrapInArray` en una definición de metadatos porque este retorna el valor de una expresiones qué se ajusta al subconjunto de Javascript restringido del compilador.
|
You can call the `wrapInArray` in a metadata definition because it returns the value of an expression that conforms to the compiler's restrictive JavaScript subset.
|
||||||
|
|
||||||
Puede usar `wrapInArray()` así:
|
You might use `wrapInArray()` like this:
|
||||||
|
|
||||||
```typescript
|
```typescript
|
||||||
@NgModule({
|
@NgModule({
|
||||||
@ -481,7 +486,7 @@ Puede usar `wrapInArray()` así:
|
|||||||
export class TypicalModule {}
|
export class TypicalModule {}
|
||||||
```
|
```
|
||||||
|
|
||||||
El compilador trata este uso como si hubieras escrito:
|
The compiler treats this usage as if you had written:
|
||||||
|
|
||||||
```typescript
|
```typescript
|
||||||
@NgModule({
|
@NgModule({
|
||||||
@ -489,19 +494,19 @@ El compilador trata este uso como si hubieras escrito:
|
|||||||
})
|
})
|
||||||
export class TypicalModule {}
|
export class TypicalModule {}
|
||||||
```
|
```
|
||||||
|
The Angular [`RouterModule`](api/router/RouterModule) exports two macro static methods, `forRoot` and `forChild`, to help declare root and child routes.
|
||||||
El [`RouterModule`](api/router/RouterModule) de Angular exporta dos métodos estáticos, `forRoot` y `forChild` para ayudar a declarar rutas raíz e hijas.
|
Review the [source code](https://github.com/angular/angular/blob/master/packages/router/src/router_module.ts#L139 "RouterModule.forRoot source code")
|
||||||
Revisa el [código fuente](https://github.com/angular/angular/blob/master/packages/router/src/router_module.ts#L139 "RouterModule.forRoot source code") para estos métodos para ver como los macros puede simplificar la configuración de complejos [NgModules](guide/ngmodules).
|
for these methods to see how macros can simplify configuration of complex [NgModules](guide/ngmodules).
|
||||||
|
|
||||||
{@a metadata-rewriting}
|
{@a metadata-rewriting}
|
||||||
|
|
||||||
### Re escribiendo metadatos
|
### Metadata rewriting
|
||||||
|
|
||||||
El compilador trata a los objetos literales que contengan los campos `useClass`, `useValue`, `useFactory` y `data` específicamente, convirtiendo la expresión inicializando uno de estos campos en una variable exportada que reemplaza la expresión
|
The compiler treats object literals containing the fields `useClass`, `useValue`, `useFactory`, and `data` specially, converting the expression initializing one of these fields into an exported variable that replaces the expression.
|
||||||
|
This process of rewriting these expressions removes all the restrictions on what can be in them because
|
||||||
|
the compiler doesn't need to know the expression's value—it just needs to be able to generate a reference to the value.
|
||||||
|
|
||||||
Este proceso de rescribir estas expresiones remueve todo las restricciones que pueden estar en el, porque el compilador no necesita conocer el valor de las expresiones solo necesita poder generar una referencia al valor.
|
You might write something like:
|
||||||
|
|
||||||
Puedes escribir algo como:
|
|
||||||
|
|
||||||
```typescript
|
```typescript
|
||||||
class TypicalServer {
|
class TypicalServer {
|
||||||
@ -514,8 +519,8 @@ class TypicalServer {
|
|||||||
export class TypicalModule {}
|
export class TypicalModule {}
|
||||||
```
|
```
|
||||||
|
|
||||||
Sin la reescritura, esto sería invalido por que las lambdas no son soportadas y `TypicalServer` no esta exportada.
|
Without rewriting, this would be invalid because lambdas are not supported and `TypicalServer` is not exported.
|
||||||
Para permitirlo, el compilador automáticamente re escribe esto a algo como:
|
To allow this, the compiler automatically rewrites this to something like:
|
||||||
|
|
||||||
```typescript
|
```typescript
|
||||||
class TypicalServer {
|
class TypicalServer {
|
||||||
@ -530,38 +535,40 @@ export const ɵ0 = () => new TypicalServer();
|
|||||||
export class TypicalModule {}
|
export class TypicalModule {}
|
||||||
```
|
```
|
||||||
|
|
||||||
Esto permite que el compilador genere una referencia hacia `ɵ0` en la fabrica sin tener que conocer cual es el valor de `ɵ0`.
|
This allows the compiler to generate a reference to `ɵ0` in the factory without having to know what the value of `ɵ0` contains.
|
||||||
|
|
||||||
El compilador hace la reescritura durante la emisión de el archivo `.js`.
|
The compiler does the rewriting during the emit of the `.js` file.
|
||||||
Sin embargo, no reescribe el archivo `.d.ts`, entonces TypeScript no lo reconoce como una exportación y esto no interfiere con la API exportada de los módulos ES.
|
It does not, however, rewrite the `.d.ts` file, so TypeScript doesn't recognize it as being an export. and it does not interfere with the ES module's exported API.
|
||||||
|
|
||||||
|
|
||||||
{@a binding-expression-validation}
|
{@a binding-expression-validation}
|
||||||
|
|
||||||
## Fase 3: Verificación de tipos en las plantillas
|
## Phase 3: Template type checking
|
||||||
|
|
||||||
Una de las características más útiles del compilador de Angular es la habilidad de comprobar el tipado de las expresiones dentro de las plantillas y capturar cualquier error antes de que ellos causen fallas en tiempo de ejecución.
|
One of the Angular compiler's most helpful features is the ability to type-check expressions within templates, and catch any errors before they cause crashes at runtime.
|
||||||
|
In the template type-checking phase, the Angular template compiler uses the TypeScript compiler to validate the binding expressions in templates.
|
||||||
|
|
||||||
En la fase de verificación de tipos en las plantillas, el compilador de plantillas de Angular usa a el compilador de TypeScript para validar las expresiones con enlazadas a datos en las plantillas.
|
Enable this phase explicitly by adding the compiler option `"fullTemplateTypeCheck"` in the `"angularCompilerOptions"` of the project's TypeScript configuration file
|
||||||
|
(see [Angular Compiler Options](guide/angular-compiler-options)).
|
||||||
Habilite esta fase explícitamente agregando la opción del compilador `"fullTemplateTypeCheck"` en las `"angularCompilerOptions"` del archivo de configuración del proyecto TypeScript (mira [Opciones del compilador de Angular](guide/angular-compiler-options)).
|
|
||||||
|
|
||||||
<div class="alert is-helpful">
|
<div class="alert is-helpful">
|
||||||
|
|
||||||
En [Angular Ivy](guide/ivy), la verificación de tipos para las plantillas a sido completamente reescrita para ser más capaz así como más estricto, esto significa poder capturar una variedad de nuevos errores que antes el verificador de tipos no podia detectar.
|
In [Angular Ivy](guide/ivy), the template type checker has been completely rewritten to be more capable as well as stricter, meaning it can catch a variety of new errors that the previous type checker would not detect.
|
||||||
|
|
||||||
Como resultado, las plantillas que previamente se compilarón bajo `View Engine` pueden fallar con el verificador de tipos bajo `Ivy`. Esto puede pasar por que el verificador de Ivy captura errores genuinos o porque el código de la aplicación no esta tipado correctamente o porque la aplicación usa librerías en las cuales el tipado es incorrecto o no es lo suficientemente especifico.
|
As a result, templates that previously compiled under View Engine can fail type checking under Ivy. This can happen because Ivy's stricter checking catches genuine errors, or because application code is not typed correctly, or because the application uses libraries in which typings are inaccurate or not specific enough.
|
||||||
|
|
||||||
Este verificador de tipos estricto no esta habilitado por defecto el la version 9 pero puedes habilitarlo configurando la opción `strictTemplates`.
|
This stricter type checking is not enabled by default in version 9, but can be enabled by setting the `strictTemplates` configuration option.
|
||||||
Nosotros esperamos hacer que el verificador de tipos estricto este habilitado por defecto en el futuro.
|
We do expect to make strict type checking the default in the future.
|
||||||
|
|
||||||
Para más información acerca de las opciones del verificador de tipos y más acerca de mejoras hacia la verificación de tipos en plantillas en la version 9 en adelante, mira [Verificando tipos en plantillas](guide/template-typecheck).
|
For more information about type-checking options, and about improvements to template type checking in version 9 and above, see [Template type checking](guide/template-typecheck).
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
La validación de templates produce mensajes de error cuando un error de tipo es detectado en una plantilla con una expresión con enlace de datos, similar a como los errores de tipado son reportados por el compilador de TypeScript contra el código en un archivo `.ts`.
|
Template validation produces error messages when a type error is detected in a template binding
|
||||||
|
expression, similar to how type errors are reported by the TypeScript compiler against code in a `.ts`
|
||||||
|
file.
|
||||||
|
|
||||||
Por ejemplo, considere el siguiente componente:
|
For example, consider the following component:
|
||||||
|
|
||||||
```typescript
|
```typescript
|
||||||
@Component({
|
@Component({
|
||||||
@ -573,29 +580,32 @@ Por ejemplo, considere el siguiente componente:
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
Esto produce el siguiente error:
|
This produces the following error:
|
||||||
|
|
||||||
```
|
```
|
||||||
my.component.ts.MyComponent.html(1,1): : Property 'addresss' does not exist on type 'Person'. Did you mean 'address'?
|
my.component.ts.MyComponent.html(1,1): : Property 'addresss' does not exist on type 'Person'. Did you mean 'address'?
|
||||||
```
|
```
|
||||||
|
|
||||||
El archivo reporta el mensaje de error, `my.component.ts.MyComponent.html`, es un archivo sintético generado por el compilador de plantillas que espera que tenga contenido de la clase `MyComponent`.
|
The file name reported in the error message, `my.component.ts.MyComponent.html`, is a synthetic file
|
||||||
El compilador nunca escribe un archivo en el disco.
|
generated by the template compiler that holds contents of the `MyComponent` class template.
|
||||||
Los números de línea y columna son relativos a la plantilla de cadena en el anotación `@Component` de la clase, `MyComponent` en este caso.
|
The compiler never writes this file to disk.
|
||||||
Si un componente usa `templateUrl` en vez de `template`, los errores son reportados en el archivo HTML referenciado por el `templateUrl` en vez de un archivo sintético.
|
The line and column numbers are relative to the template string in the `@Component` annotation of the class, `MyComponent` in this case.
|
||||||
|
If a component uses `templateUrl` instead of `template`, the errors are reported in the HTML file referenced by the `templateUrl` instead of a synthetic file.
|
||||||
|
|
||||||
La ubicación del error esta en el inicio del nodo de texto que contiene la expresión interpolada con el error.
|
The error location is the beginning of the text node that contains the interpolation expression with the error.
|
||||||
Si el error esta en un atributo con enlace de datos como `[value]="person.address.street"`, la ubicación del error es la ubicación del atributo que contiene el error.
|
If the error is in an attribute binding such as `[value]="person.address.street"`, the error
|
||||||
|
location is the location of the attribute that contains the error.
|
||||||
La validación usa el verificador de tipos de TypeScript y las opciones suministradas hacia el compilador de TypeScript para controlar qué tan detallada es la validación de tipos.
|
|
||||||
Por ejemplo, si el `strictTypeChecks` es especificado, el error ```my.component.ts.MyComponent.html(1,1): : Object is possibly 'undefined'``` es reportado así como el mensaje de error anterior.
|
|
||||||
|
|
||||||
|
The validation uses the TypeScript type checker and the options supplied to the TypeScript compiler to control how detailed the type validation is.
|
||||||
|
For example, if the `strictTypeChecks` is specified, the error
|
||||||
|
```my.component.ts.MyComponent.html(1,1): : Object is possibly 'undefined'```
|
||||||
|
is reported as well as the above error message.
|
||||||
|
|
||||||
### Type narrowing
|
### Type narrowing
|
||||||
|
|
||||||
La expresión usada en un directiva `ngIf` es usada para estrechar uniones de tipo en el compilador de plantillas de Angular, de la misma manera que la expresión `if` lo hace en TypeScript.
|
The expression used in an `ngIf` directive is used to narrow type unions in the Angular
|
||||||
Por ejemplo, para evitar el error `Object is possibly 'undefined'` en la plantilla de arriba, modifícalo para que solo emita la interpolación si el valor de `person` esta inicializado como se muestra en seguida:
|
template compiler, the same way the `if` expression does in TypeScript.
|
||||||
|
For example, to avoid `Object is possibly 'undefined'` error in the template above, modify it to only emit the interpolation if the value of `person` is initialized as shown below:
|
||||||
|
|
||||||
```typescript
|
```typescript
|
||||||
@Component({
|
@Component({
|
||||||
@ -607,17 +617,16 @@ Por ejemplo, para evitar el error `Object is possibly 'undefined'` en la plantil
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
Usando `*ngIf` permite que el compilador de TypeScript infiera que el atributo `person` usado en la expresión enlanzada nunca séra `undefined`.
|
Using `*ngIf` allows the TypeScript compiler to infer that the `person` used in the binding expression will never be `undefined`.
|
||||||
|
|
||||||
Para más información acerca del estrechamiento de tipos de entrada, mira [Coerción del establecedor de entrada](guide/template-typecheck#input-setter-coercion) y [Mejorando el verificar de tipos para directivas personalizadas](guide/structural-directives#directive-type-checks).
|
For more information about input type narrowing, see [Input setter coercion](guide/template-typecheck#input-setter-coercion) and [Improving template type checking for custom directives](guide/structural-directives#directive-type-checks).
|
||||||
|
|
||||||
### Operador de aserción de tipo nulo
|
### Non-null type assertion operator
|
||||||
|
|
||||||
Use el [operador de aserción de tipo nulo](guide/template-expression-operators#non-null-assertion-operator) para reprimir el error `Object is possibly 'undefined'` cuando es inconveniente usar `*ngIf` o cuando alguna restricción en el componente asegura que la expresión siempre es no nula cuando la expresión con enlace de datos es interpolada.
|
Use the [non-null type assertion operator](guide/template-expression-operators#non-null-assertion-operator) to suppress the `Object is possibly 'undefined'` error when it is inconvenient to use `*ngIf` or when some constraint in the component ensures that the expression is always non-null when the binding expression is interpolated.
|
||||||
|
|
||||||
En el siguiente ejemplo, las propiedades `person` y `address` son siempre configuradas juntas, implicando que `address` siempre es no nula si `person` es no nula.
|
|
||||||
No existe una forma conveniente de describir esta restricción a TypeScript y a el compilador de plantillas pero el error es suprimido en el ejemplo por usar `address!.street`.
|
|
||||||
|
|
||||||
|
In the following example, the `person` and `address` properties are always set together, implying that `address` is always non-null if `person` is non-null.
|
||||||
|
There is no convenient way to describe this constraint to TypeScript and the template compiler, but the error is suppressed in the example by using `address!.street`.
|
||||||
|
|
||||||
```typescript
|
```typescript
|
||||||
@Component({
|
@Component({
|
||||||
@ -635,9 +644,9 @@ No existe una forma conveniente de describir esta restricción a TypeScript y a
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
El operador de aserción de tipo nulo debería usarse con moderación ya que la refactorización del componente podría romper esta restricción.
|
The non-null assertion operator should be used sparingly as refactoring of the component might break this constraint.
|
||||||
|
|
||||||
En este ejemplo es recomendable incluir la verificación de `address` en el `*ngIf` como se muestra a continuación:
|
In this example it is recommended to include the checking of `address` in the `*ngIf` as shown below:
|
||||||
|
|
||||||
```typescript
|
```typescript
|
||||||
@Component({
|
@Component({
|
||||||
|
@ -1,318 +0,0 @@
|
|||||||
|
|
||||||
# Binding syntax: an overview
|
|
||||||
|
|
||||||
Data-binding is a mechanism for coordinating what users see, specifically
|
|
||||||
with application data values.
|
|
||||||
While you could push values to and pull values from HTML,
|
|
||||||
the application is easier to write, read, and maintain if you turn these tasks over to a binding framework.
|
|
||||||
You simply declare bindings between binding sources, target HTML elements, and let the framework do the rest.
|
|
||||||
|
|
||||||
<div class="alert is-helpful">
|
|
||||||
|
|
||||||
See the <live-example></live-example> for a working example containing the code snippets in this guide.
|
|
||||||
|
|
||||||
</div>
|
|
||||||
|
|
||||||
Angular provides many kinds of data-binding. Binding types can be grouped into three categories distinguished by the direction of data flow:
|
|
||||||
|
|
||||||
* From the _source-to-view_
|
|
||||||
* From _view-to-source_
|
|
||||||
* Two-way sequence: _view-to-source-to-view_
|
|
||||||
|
|
||||||
<style>
|
|
||||||
td, th {vertical-align: top}
|
|
||||||
</style>
|
|
||||||
|
|
||||||
<table width="100%">
|
|
||||||
<col width="30%">
|
|
||||||
</col>
|
|
||||||
<col width="50%">
|
|
||||||
</col>
|
|
||||||
<col width="20%">
|
|
||||||
</col>
|
|
||||||
<tr>
|
|
||||||
<th>
|
|
||||||
Type
|
|
||||||
</th>
|
|
||||||
<th>
|
|
||||||
Syntax
|
|
||||||
</th>
|
|
||||||
<th>
|
|
||||||
Category
|
|
||||||
</th>
|
|
||||||
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>
|
|
||||||
Interpolation<br>
|
|
||||||
Property<br>
|
|
||||||
Attribute<br>
|
|
||||||
Class<br>
|
|
||||||
Style
|
|
||||||
</td>
|
|
||||||
<td>
|
|
||||||
|
|
||||||
<code-example>
|
|
||||||
{{expression}}
|
|
||||||
[target]="expression"
|
|
||||||
bind-target="expression"
|
|
||||||
</code-example>
|
|
||||||
|
|
||||||
</td>
|
|
||||||
|
|
||||||
<td>
|
|
||||||
One-way<br>from data source<br>to view target
|
|
||||||
</td>
|
|
||||||
<tr>
|
|
||||||
<td>
|
|
||||||
Event
|
|
||||||
</td>
|
|
||||||
<td>
|
|
||||||
<code-example>
|
|
||||||
(target)="statement"
|
|
||||||
on-target="statement"
|
|
||||||
</code-example>
|
|
||||||
</td>
|
|
||||||
|
|
||||||
<td>
|
|
||||||
One-way<br>from view target<br>to data source
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>
|
|
||||||
Two-way
|
|
||||||
</td>
|
|
||||||
<td>
|
|
||||||
<code-example>
|
|
||||||
[(target)]="expression"
|
|
||||||
bindon-target="expression"
|
|
||||||
</code-example>
|
|
||||||
</td>
|
|
||||||
<td>
|
|
||||||
Two-way
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
</tr>
|
|
||||||
</table>
|
|
||||||
|
|
||||||
Binding types other than interpolation have a **target name** to the left of the equal sign, either surrounded by punctuation, `[]` or `()`,
|
|
||||||
or preceded by a prefix: `bind-`, `on-`, `bindon-`.
|
|
||||||
|
|
||||||
The *target* of a binding is the property or event inside the binding punctuation: `[]`, `()` or `[()]`.
|
|
||||||
|
|
||||||
Every public member of a **source** directive is automatically available for binding.
|
|
||||||
You don't have to do anything special to access a directive member in a template expression or statement.
|
|
||||||
|
|
||||||
|
|
||||||
### Data-binding and HTML
|
|
||||||
|
|
||||||
In the normal course of HTML development, you create a visual structure with HTML elements, and
|
|
||||||
you modify those elements by setting element attributes with string constants.
|
|
||||||
|
|
||||||
```html
|
|
||||||
<div class="special">Plain old HTML</div>
|
|
||||||
<img src="images/item.png">
|
|
||||||
<button disabled>Save</button>
|
|
||||||
```
|
|
||||||
|
|
||||||
With data-binding, you can control things like the state of a button:
|
|
||||||
|
|
||||||
<code-example path="binding-syntax/src/app/app.component.html" region="disabled-button" header="src/app/app.component.html"></code-example>
|
|
||||||
|
|
||||||
Notice that the binding is to the `disabled` property of the button's DOM element,
|
|
||||||
**not** the attribute. This applies to data-binding in general. Data-binding works with *properties* of DOM elements, components, and directives, not HTML *attributes*.
|
|
||||||
|
|
||||||
{@a html-attribute-vs-dom-property}
|
|
||||||
|
|
||||||
### HTML attribute vs. DOM property
|
|
||||||
|
|
||||||
The distinction between an HTML attribute and a DOM property is key to understanding
|
|
||||||
how Angular binding works. **Attributes are defined by HTML. Properties are accessed from DOM (Document Object Model) nodes.**
|
|
||||||
|
|
||||||
* A few HTML attributes have 1:1 mapping to properties; for example, `id`.
|
|
||||||
|
|
||||||
* Some HTML attributes don't have corresponding properties; for example, `aria-*`.
|
|
||||||
|
|
||||||
* Some DOM properties don't have corresponding attributes; for example, `textContent`.
|
|
||||||
|
|
||||||
It is important to remember that *HTML attribute* and the *DOM property* are different things, even when they have the same name.
|
|
||||||
In Angular, the only role of HTML attributes is to initialize element and directive state.
|
|
||||||
|
|
||||||
**Template binding works with *properties* and *events*, not *attributes*.**
|
|
||||||
|
|
||||||
When you write a data-binding, you're dealing exclusively with the *DOM properties* and *events* of the target object.
|
|
||||||
|
|
||||||
<div class="alert is-helpful">
|
|
||||||
|
|
||||||
This general rule can help you build a mental model of attributes and DOM properties:
|
|
||||||
**Attributes initialize DOM properties and then they are done.
|
|
||||||
Property values can change; attribute values can't.**
|
|
||||||
|
|
||||||
There is one exception to this rule.
|
|
||||||
Attributes can be changed by `setAttribute()`, which re-initializes corresponding DOM properties.
|
|
||||||
|
|
||||||
</div>
|
|
||||||
|
|
||||||
For more information, see the [MDN Interfaces documentation](https://developer.mozilla.org/en-US/docs/Web/API#Interfaces) which has API docs for all the standard DOM elements and their properties.
|
|
||||||
Comparing the [`<td>` attributes](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/td) attributes to the [`<td>` properties](https://developer.mozilla.org/en-US/docs/Web/API/HTMLTableCellElement) provides a helpful example for differentiation.
|
|
||||||
In particular, you can navigate from the attributes page to the properties via "DOM interface" link, and navigate the inheritance hierarchy up to `HTMLTableCellElement`.
|
|
||||||
|
|
||||||
|
|
||||||
#### Example 1: an `<input>`
|
|
||||||
|
|
||||||
When the browser renders `<input type="text" value="Sarah">`, it creates a
|
|
||||||
corresponding DOM node with a `value` property initialized to "Sarah".
|
|
||||||
|
|
||||||
```html
|
|
||||||
<input type="text" value="Sarah">
|
|
||||||
```
|
|
||||||
|
|
||||||
When the user enters "Sally" into the `<input>`, the DOM element `value` *property* becomes "Sally".
|
|
||||||
However, if you look at the HTML attribute `value` using `input.getAttribute('value')`, you can see that the *attribute* remains unchanged—it returns "Sarah".
|
|
||||||
|
|
||||||
The HTML attribute `value` specifies the *initial* value; the DOM `value` property is the *current* value.
|
|
||||||
|
|
||||||
To see attributes versus DOM properties in a functioning app, see the <live-example name="binding-syntax"></live-example> especially for binding syntax.
|
|
||||||
|
|
||||||
#### Example 2: a disabled button
|
|
||||||
|
|
||||||
The `disabled` attribute is another example. A button's `disabled`
|
|
||||||
*property* is `false` by default so the button is enabled.
|
|
||||||
|
|
||||||
When you add the `disabled` *attribute*, its presence alone
|
|
||||||
initializes the button's `disabled` *property* to `true`
|
|
||||||
so the button is disabled.
|
|
||||||
|
|
||||||
```html
|
|
||||||
<button disabled>Test Button</button>
|
|
||||||
```
|
|
||||||
|
|
||||||
Adding and removing the `disabled` *attribute* disables and enables the button.
|
|
||||||
However, the value of the *attribute* is irrelevant,
|
|
||||||
which is why you cannot enable a button by writing `<button disabled="false">Still Disabled</button>`.
|
|
||||||
|
|
||||||
To control the state of the button, set the `disabled` *property*,
|
|
||||||
|
|
||||||
<div class="alert is-helpful">
|
|
||||||
|
|
||||||
Though you could technically set the `[attr.disabled]` attribute binding, the values are different in that the property binding requires to a boolean value, while its corresponding attribute binding relies on whether the value is `null` or not. Consider the following:
|
|
||||||
|
|
||||||
```html
|
|
||||||
<input [disabled]="condition ? true : false">
|
|
||||||
<input [attr.disabled]="condition ? 'disabled' : null">
|
|
||||||
```
|
|
||||||
|
|
||||||
Generally, use property binding over attribute binding as it is more intuitive (being a boolean value), has a shorter syntax, and is more performant.
|
|
||||||
|
|
||||||
</div>
|
|
||||||
|
|
||||||
|
|
||||||
To see the `disabled` button example in a functioning app, see the <live-example name="binding-syntax"></live-example> especially for binding syntax. This example shows you how to toggle the disabled property from the component.
|
|
||||||
|
|
||||||
## Binding types and targets
|
|
||||||
|
|
||||||
The **target of a data-binding** is something in the DOM.
|
|
||||||
Depending on the binding type, the target can be a property (element, component, or directive),
|
|
||||||
an event (element, component, or directive), or sometimes an attribute name.
|
|
||||||
The following table summarizes the targets for the different binding types.
|
|
||||||
|
|
||||||
<style>
|
|
||||||
td, th {vertical-align: top}
|
|
||||||
</style>
|
|
||||||
|
|
||||||
<table width="100%">
|
|
||||||
<col width="10%">
|
|
||||||
</col>
|
|
||||||
<col width="15%">
|
|
||||||
</col>
|
|
||||||
<col width="75%">
|
|
||||||
</col>
|
|
||||||
<tr>
|
|
||||||
<th>
|
|
||||||
Type
|
|
||||||
</th>
|
|
||||||
<th>
|
|
||||||
Target
|
|
||||||
</th>
|
|
||||||
<th>
|
|
||||||
Examples
|
|
||||||
</th>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>
|
|
||||||
Property
|
|
||||||
</td>
|
|
||||||
<td>
|
|
||||||
Element property<br>
|
|
||||||
Component property<br>
|
|
||||||
Directive property
|
|
||||||
</td>
|
|
||||||
<td>
|
|
||||||
<code>src</code>, <code>hero</code>, and <code>ngClass</code> in the following:
|
|
||||||
<code-example path="template-syntax/src/app/app.component.html" region="property-binding-syntax-1"></code-example>
|
|
||||||
<!-- For more information, see [Property Binding](guide/property-binding). -->
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>
|
|
||||||
Event
|
|
||||||
</td>
|
|
||||||
<td>
|
|
||||||
Element event<br>
|
|
||||||
Component event<br>
|
|
||||||
Directive event
|
|
||||||
</td>
|
|
||||||
<td>
|
|
||||||
<code>click</code>, <code>deleteRequest</code>, and <code>myClick</code> in the following:
|
|
||||||
<code-example path="template-syntax/src/app/app.component.html" region="event-binding-syntax-1"></code-example>
|
|
||||||
<!-- KW--Why don't these links work in the table? -->
|
|
||||||
<!-- <div>For more information, see [Event Binding](guide/event-binding).</div> -->
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>
|
|
||||||
Two-way
|
|
||||||
</td>
|
|
||||||
<td>
|
|
||||||
Event and property
|
|
||||||
</td>
|
|
||||||
<td>
|
|
||||||
<code-example path="template-syntax/src/app/app.component.html" region="2-way-binding-syntax-1"></code-example>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>
|
|
||||||
Attribute
|
|
||||||
</td>
|
|
||||||
<td>
|
|
||||||
Attribute
|
|
||||||
(the exception)
|
|
||||||
</td>
|
|
||||||
<td>
|
|
||||||
<code-example path="template-syntax/src/app/app.component.html" region="attribute-binding-syntax-1"></code-example>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>
|
|
||||||
Class
|
|
||||||
</td>
|
|
||||||
<td>
|
|
||||||
<code>class</code> property
|
|
||||||
</td>
|
|
||||||
<td>
|
|
||||||
<code-example path="template-syntax/src/app/app.component.html" region="class-binding-syntax-1"></code-example>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>
|
|
||||||
Style
|
|
||||||
</td>
|
|
||||||
<td>
|
|
||||||
<code>style</code> property
|
|
||||||
</td>
|
|
||||||
<td>
|
|
||||||
<code-example path="template-syntax/src/app/app.component.html" region="style-binding-syntax-1"></code-example>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
</table>
|
|
||||||
|
|
@ -1,21 +1,23 @@
|
|||||||
|
|
||||||
# Sintaxis de Enlace: una visión general
|
# Binding syntax: an overview
|
||||||
|
|
||||||
El enlace de datos es un mecanismo utilizado para coordinar los valores de los datos que los usuarios visualizan en la aplicación.
|
Data-binding is a mechanism for coordinating what users see, specifically
|
||||||
Aunque puedas insertar y actualizar valores en el HTML, la aplicación es más fácil de escribir, leer y mantener si tu le dejas esas tareas al framework de enlace.
|
with application data values.
|
||||||
Por lo que simplemente debes declarar enlaces entre los datos del modelo y los elementos HTML y dejar al framework que haga el resto del trabajo.
|
While you could push values to and pull values from HTML,
|
||||||
|
the application is easier to write, read, and maintain if you turn these tasks over to a binding framework.
|
||||||
|
You simply declare bindings between binding sources, target HTML elements, and let the framework do the rest.
|
||||||
|
|
||||||
<div class="alert is-helpful">
|
<div class="alert is-helpful">
|
||||||
|
|
||||||
Consulta la <live-example>aplicación de muestra</live-example> que es un ejemplo funcional que contiene los fragmentos de código utilizados en esta guía.
|
See the <live-example></live-example> for a working example containing the code snippets in this guide.
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
Angular proporciona muchas formas para manejar el enlace de datos. Los tipos de enlace se pueden agrupar en tres categorías que se distinguen de acuerdo a la dirección del flujo de datos:
|
Angular provides many kinds of data-binding. Binding types can be grouped into three categories distinguished by the direction of data flow:
|
||||||
|
|
||||||
* Desde el _modelo-hacia-vista_
|
* From the _source-to-view_
|
||||||
* Desde la _vista-hacia-modelo_
|
* From _view-to-source_
|
||||||
* Secuencia Bidireccional: _vista-hacia-modelo-hacia-vista_
|
* Two-way sequence: _view-to-source-to-view_
|
||||||
|
|
||||||
<style>
|
<style>
|
||||||
td, th {vertical-align: top}
|
td, th {vertical-align: top}
|
||||||
@ -30,23 +32,23 @@ Angular proporciona muchas formas para manejar el enlace de datos. Los tipos de
|
|||||||
</col>
|
</col>
|
||||||
<tr>
|
<tr>
|
||||||
<th>
|
<th>
|
||||||
Tipo
|
Type
|
||||||
</th>
|
</th>
|
||||||
<th>
|
<th>
|
||||||
Sintaxis
|
Syntax
|
||||||
</th>
|
</th>
|
||||||
<th>
|
<th>
|
||||||
Categoría
|
Category
|
||||||
</th>
|
</th>
|
||||||
|
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td>
|
<td>
|
||||||
Interpolación<br>
|
Interpolation<br>
|
||||||
Propiedad<br>
|
Property<br>
|
||||||
Atributo<br>
|
Attribute<br>
|
||||||
Clase<br>
|
Class<br>
|
||||||
Estilos
|
Style
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
|
|
||||||
@ -59,11 +61,11 @@ Angular proporciona muchas formas para manejar el enlace de datos. Los tipos de
|
|||||||
</td>
|
</td>
|
||||||
|
|
||||||
<td>
|
<td>
|
||||||
Una sola dirección<br>desde el modelo de datos<br>hacia la vista
|
One-way<br>from data source<br>to view target
|
||||||
</td>
|
</td>
|
||||||
<tr>
|
<tr>
|
||||||
<td>
|
<td>
|
||||||
Evento
|
Event
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
<code-example>
|
<code-example>
|
||||||
@ -73,12 +75,12 @@ Angular proporciona muchas formas para manejar el enlace de datos. Los tipos de
|
|||||||
</td>
|
</td>
|
||||||
|
|
||||||
<td>
|
<td>
|
||||||
Una sola dirección<br>desde la vista<br>hacia el modelo de datos
|
One-way<br>from view target<br>to data source
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td>
|
<td>
|
||||||
Bidireccional
|
Two-way
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
<code-example>
|
<code-example>
|
||||||
@ -87,123 +89,132 @@ Angular proporciona muchas formas para manejar el enlace de datos. Los tipos de
|
|||||||
</code-example>
|
</code-example>
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
Bidireccional
|
Two-way
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
</tr>
|
</tr>
|
||||||
</table>
|
</table>
|
||||||
|
|
||||||
Los tipos de enlace distintos a la interporlación tienen un **nombre de destino** hacia la izquierda del signo igual, están rodeados por los signos de puntación `[]` o `()`, o bien están precedidos por el prefijo: `bind-`, `on-`, `bindon-`.
|
Binding types other than interpolation have a **target name** to the left of the equal sign, either surrounded by punctuation, `[]` or `()`,
|
||||||
|
or preceded by a prefix: `bind-`, `on-`, `bindon-`.
|
||||||
|
|
||||||
El *destino* de un enlace es la propiedad o evento situado dentro de los signos de puntuación: `[]`, `()` or `[()]`.
|
The *target* of a binding is the property or event inside the binding punctuation: `[]`, `()` or `[()]`.
|
||||||
|
|
||||||
Cada miembro <span class="x x-first x-last">público</span> de una directiva **fuente** <span class="x x-first x-last">está</span> disponible automaticamente para ser utilizada con los enlaces.
|
Every public member of a **source** directive is automatically available for binding.
|
||||||
No es necesario hacer nada especial para poder acceder al miembro de una directiva en una expresión o declaración de plantilla.
|
You don't have to do anything special to access a directive member in a template expression or statement.
|
||||||
|
|
||||||
### Enlace de Datos y el HTML
|
|
||||||
|
|
||||||
En condiciones normales para un desarrollo HTML, primero se crea la estructura visual con los elementos HTML y luego se modifican dichos elementos estableciendo los atributos de dichos elementos utilizando una cadena de caracteres.
|
### Data-binding and HTML
|
||||||
|
|
||||||
|
In the normal course of HTML development, you create a visual structure with HTML elements, and
|
||||||
|
you modify those elements by setting element attributes with string constants.
|
||||||
|
|
||||||
```html
|
```html
|
||||||
<div class="special">HTML Simple</div>
|
<div class="special">Plain old HTML</div>
|
||||||
<img src="images/item.png">
|
<img src="images/item.png">
|
||||||
<button disabled>Guardar</button>
|
<button disabled>Save</button>
|
||||||
```
|
```
|
||||||
|
|
||||||
Usando el enlace de datos, puedes controlar cosas como el estado de un botón:
|
With data-binding, you can control things like the state of a button:
|
||||||
|
|
||||||
<code-example path="binding-syntax/src/app/app.component.html" region="disabled-button" header="src/app/app.component.html"></code-example>
|
<code-example path="binding-syntax/src/app/app.component.html" region="disabled-button" header="src/app/app.component.html"></code-example>
|
||||||
|
|
||||||
Puedes notar que el enlace se realiza a la propiedad `disabled` del elemento botón del DOM,
|
Notice that the binding is to the `disabled` property of the button's DOM element,
|
||||||
**no** al atributo. Esto aplica al enlace de datos en general. El enlace de datos funciona con las *propiedades* de los elementos, componentes y directivas del DOM, no con los *atributos* HTML
|
**not** the attribute. This applies to data-binding in general. Data-binding works with *properties* of DOM elements, components, and directives, not HTML *attributes*.
|
||||||
|
|
||||||
{@a html-attribute-vs-dom-property}
|
{@a html-attribute-vs-dom-property}
|
||||||
|
|
||||||
### Atributos HTML vs. Propiedades del DOM
|
### HTML attribute vs. DOM property
|
||||||
|
|
||||||
Distinguir la diferencia entre un atributo HTML y una propiedad del DOM es clave para comprender como funciona el enlace en Angular. **Los attributos son definidos por el HTML. Las propiedades se acceden desde los nodos del DOM (Document Object Model).**
|
The distinction between an HTML attribute and a DOM property is key to understanding
|
||||||
|
how Angular binding works. **Attributes are defined by HTML. Properties are accessed from DOM (Document Object Model) nodes.**
|
||||||
|
|
||||||
* Muy pocos atributos HTML tienen una relación 1:1 con las propiedades; por ejemplo el, `id`.
|
* A few HTML attributes have 1:1 mapping to properties; for example, `id`.
|
||||||
|
|
||||||
* Algunos atributos HTML no tienen su correspondencia en propiedades; como por ejemplo, `aria-*`.
|
* Some HTML attributes don't have corresponding properties; for example, `aria-*`.
|
||||||
|
|
||||||
* Algunas propiedades del DOM no tienen su correspondencia hacia atributos; como por ejemplo, `textContent`.
|
* Some DOM properties don't have corresponding attributes; for example, `textContent`.
|
||||||
|
|
||||||
Es importante recordar que los *atributos HTML* y las *propiedades del DOM* son cosas muy diferentes, incluso cuando tienen el mismo nombre.
|
It is important to remember that *HTML attribute* and the *DOM property* are different things, even when they have the same name.
|
||||||
En Angular, el único rol de los atributos HTML es el de inicializar el estado de los elementos y las directivas.
|
In Angular, the only role of HTML attributes is to initialize element and directive state.
|
||||||
|
|
||||||
**El enlace de plantilla funciona con *propiedades* y *eventos*, no con *atributos*.**
|
**Template binding works with *properties* and *events*, not *attributes*.**
|
||||||
|
|
||||||
Cuando escribes un enlace de datos, se trata exclusivamente sobre las *propiedades del DOM* and *eventos* del objeto de destino.
|
When you write a data-binding, you're dealing exclusively with the *DOM properties* and *events* of the target object.
|
||||||
|
|
||||||
<div class="alert is-helpful">
|
<div class="alert is-helpful">
|
||||||
|
|
||||||
Esta regla general puede ayudarnos a crear un modelo mental de los atributos y las propiedades del DOM:
|
This general rule can help you build a mental model of attributes and DOM properties:
|
||||||
**Los atributos inicializan las propiedades del DOM y cuando eso ya esta hecho, los valores de las propiedades pueden cambiar, mientras que los atributos no lo pueden hacer.**
|
**Attributes initialize DOM properties and then they are done.
|
||||||
|
Property values can change; attribute values can't.**
|
||||||
|
|
||||||
Solamente hay una excepción a la regla.
|
There is one exception to this rule.
|
||||||
Los atributos pueden cambiarse usando el método `setAttribute()`, el cual re-inicializa las propiedades del DOM correspondientes.
|
Attributes can be changed by `setAttribute()`, which re-initializes corresponding DOM properties.
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
Para más información, consulta la [Documentación de Interfaces MDN](https://developer.mozilla.org/en-US/docs/Web/API#Interfaces) que contiene los documentos de la API para todos los elementos estándar del DOM y sus propiedades.
|
For more information, see the [MDN Interfaces documentation](https://developer.mozilla.org/en-US/docs/Web/API#Interfaces) which has API docs for all the standard DOM elements and their properties.
|
||||||
Comparar los atributos [`<td>` atributos](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/td) con las propiedades [`<td>` propiedades](https://developer.mozilla.org/en-US/docs/Web/API/HTMLTableCellElement) nos proporciona un ejemplo útil para poder diferenciar estos dos términos de una mejor manera.
|
Comparing the [`<td>` attributes](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/td) attributes to the [`<td>` properties](https://developer.mozilla.org/en-US/docs/Web/API/HTMLTableCellElement) provides a helpful example for differentiation.
|
||||||
En particular, se puede navegar de la página de atributos a la página de propiedades por medio del enlace "Interfaz del DOM", y navegar la jerarquía de la herencia hasta `HTMLTableCellElement`.
|
In particular, you can navigate from the attributes page to the properties via "DOM interface" link, and navigate the inheritance hierarchy up to `HTMLTableCellElement`.
|
||||||
|
|
||||||
|
|
||||||
#### Ejemplo 1: un `<input>`
|
#### Example 1: an `<input>`
|
||||||
|
|
||||||
Cuando el navegador renderiza `<input type="text" value="Sarah">`, este crea un nodo correspondiente en el DOM con la propiedad `value` inicializada con el valor de "Sarah".
|
When the browser renders `<input type="text" value="Sarah">`, it creates a
|
||||||
|
corresponding DOM node with a `value` property initialized to "Sarah".
|
||||||
|
|
||||||
```html
|
```html
|
||||||
<input type="text" value="Sarah">
|
<input type="text" value="Sarah">
|
||||||
```
|
```
|
||||||
|
|
||||||
Cuando el usuario ingresa "Sally" dentro del `<input>`, la **propiedad** `value` del elemento del DOM se convierte en "Sally".
|
When the user enters "Sally" into the `<input>`, the DOM element `value` *property* becomes "Sally".
|
||||||
Sin embargo, si tu revisas el atributo HTML `value` usando el método `input.getAttribute('value')`, puedes notar que el *atributo* no ha cambiado—por lo que returna el valor de "Sarah".
|
However, if you look at the HTML attribute `value` using `input.getAttribute('value')`, you can see that the *attribute* remains unchanged—it returns "Sarah".
|
||||||
|
|
||||||
El atributo HTML `value` especifica el valor *inicial*; la propiedad del DOM `value` es el valor *actual*.
|
The HTML attribute `value` specifies the *initial* value; the DOM `value` property is the *current* value.
|
||||||
|
|
||||||
Para consultar los atributos vs las propiedades del DOM en una aplicación funcional, consulta la <live-example name="binding-syntax">aplicación</live-example> en especial para repasar la sintaxis de enlace.
|
To see attributes versus DOM properties in a functioning app, see the <live-example name="binding-syntax"></live-example> especially for binding syntax.
|
||||||
|
|
||||||
#### Ejemplo 2: un botón desactivado
|
#### Example 2: a disabled button
|
||||||
|
|
||||||
El atributo `disabled` es otro ejemplo. La *propiedad* del botón `disabled`
|
The `disabled` attribute is another example. A button's `disabled`
|
||||||
*property* es `false` por defecto así que el botón esta activo.
|
*property* is `false` by default so the button is enabled.
|
||||||
|
|
||||||
Cuando añades el *atributo* `disabled`, su sola presencia inicializa la *propiedad* del botón `disabled` con el valor de `true` por lo que el botón esta desactivado.
|
When you add the `disabled` *attribute*, its presence alone
|
||||||
|
initializes the button's `disabled` *property* to `true`
|
||||||
|
so the button is disabled.
|
||||||
|
|
||||||
```html
|
```html
|
||||||
<button disabled>Botón de Ejemplo</button>
|
<button disabled>Test Button</button>
|
||||||
```
|
```
|
||||||
|
|
||||||
Añadir y eliminar el *atributo* `disabled` desactiva y activa el botón.
|
Adding and removing the `disabled` *attribute* disables and enables the button.
|
||||||
Sin embargo, el valor del *atributo* es irrelevante,
|
However, the value of the *attribute* is irrelevant,
|
||||||
lo cual es la razón del por qué no puedes activar un botón escribiendo `<button disabled="false">Todavía Desactivado</button>`.
|
which is why you cannot enable a button by writing `<button disabled="false">Still Disabled</button>`.
|
||||||
|
|
||||||
Para controlar el estado de un botón, establece la *propiedad* `disabled`.
|
To control the state of the button, set the `disabled` *property*,
|
||||||
|
|
||||||
<div class="alert is-helpful">
|
<div class="alert is-helpful">
|
||||||
|
|
||||||
Aunque técnicamente podrías establecer el enlace de atributo `[attr.disabled]`, los valores son diferentes ya que el enlace de propiedad necesita un valor booleano, mientras que el enlace de atributo correspondiente depende de que su valor sea `null` o no. Por lo que considera lo siguiente:
|
Though you could technically set the `[attr.disabled]` attribute binding, the values are different in that the property binding requires to a boolean value, while its corresponding attribute binding relies on whether the value is `null` or not. Consider the following:
|
||||||
|
|
||||||
```html
|
```html
|
||||||
<input [disabled]="condition ? true : false">
|
<input [disabled]="condition ? true : false">
|
||||||
<input [attr.disabled]="condition ? 'disabled' : null">
|
<input [attr.disabled]="condition ? 'disabled' : null">
|
||||||
```
|
```
|
||||||
|
|
||||||
Por lo general usa enlace de propiedades sobre enlace de atributos ya que es más intuitivo (siendo un valor booleano), tienen una sintaxis corta y es más eficaz.
|
Generally, use property binding over attribute binding as it is more intuitive (being a boolean value), has a shorter syntax, and is more performant.
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
Para ver el ejemplo del botón `disabled`, consulta la <live-example name="binding-syntax">aplicación</live-example> en especial para revisar la sintaxis de enlace. Este ejemplo muestra como alternar la propiedad disabled desde el componente.
|
|
||||||
|
|
||||||
## Tipos de enlace y objetivos
|
To see the `disabled` button example in a functioning app, see the <live-example name="binding-syntax"></live-example> especially for binding syntax. This example shows you how to toggle the disabled property from the component.
|
||||||
|
|
||||||
El **objetivo de un enlace de datos** se relaciona con algo del DOM.
|
## Binding types and targets
|
||||||
Dependiendo del tipo de enlace, el objetivo puede ser una propiedad (elemento, componente, o directiva),
|
|
||||||
un evento (elemento, componente o directiva), o incluso algunas veces el nombre de un atributo.
|
The **target of a data-binding** is something in the DOM.
|
||||||
La siguiente tabla recoge los objetivos para los diferentes tipos de enlace.
|
Depending on the binding type, the target can be a property (element, component, or directive),
|
||||||
|
an event (element, component, or directive), or sometimes an attribute name.
|
||||||
|
The following table summarizes the targets for the different binding types.
|
||||||
|
|
||||||
<style>
|
<style>
|
||||||
td, th {vertical-align: top}
|
td, th {vertical-align: top}
|
||||||
@ -218,23 +229,23 @@ La siguiente tabla recoge los objetivos para los diferentes tipos de enlace.
|
|||||||
</col>
|
</col>
|
||||||
<tr>
|
<tr>
|
||||||
<th>
|
<th>
|
||||||
Tipo
|
Type
|
||||||
</th>
|
</th>
|
||||||
<th>
|
<th>
|
||||||
Objetivo
|
Target
|
||||||
</th>
|
</th>
|
||||||
<th>
|
<th>
|
||||||
Ejemplos
|
Examples
|
||||||
</th>
|
</th>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td>
|
<td>
|
||||||
Propiedad
|
Property
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
Propiedad del elemento<br>
|
Element property<br>
|
||||||
Propiedad del componente<br>
|
Component property<br>
|
||||||
Propiedad de la directiva
|
Directive property
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
<code>src</code>, <code>hero</code>, and <code>ngClass</code> in the following:
|
<code>src</code>, <code>hero</code>, and <code>ngClass</code> in the following:
|
||||||
@ -244,12 +255,12 @@ La siguiente tabla recoge los objetivos para los diferentes tipos de enlace.
|
|||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td>
|
<td>
|
||||||
Evento
|
Event
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
Evento del elemento<br>
|
Element event<br>
|
||||||
Evento del componente<br>
|
Component event<br>
|
||||||
Evento de la directiva
|
Directive event
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
<code>click</code>, <code>deleteRequest</code>, and <code>myClick</code> in the following:
|
<code>click</code>, <code>deleteRequest</code>, and <code>myClick</code> in the following:
|
||||||
@ -260,10 +271,10 @@ La siguiente tabla recoge los objetivos para los diferentes tipos de enlace.
|
|||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td>
|
<td>
|
||||||
Bidireccional
|
Two-way
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
Eventos y propiedades
|
Event and property
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
<code-example path="template-syntax/src/app/app.component.html" region="2-way-binding-syntax-1"></code-example>
|
<code-example path="template-syntax/src/app/app.component.html" region="2-way-binding-syntax-1"></code-example>
|
||||||
@ -271,11 +282,11 @@ La siguiente tabla recoge los objetivos para los diferentes tipos de enlace.
|
|||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td>
|
<td>
|
||||||
Atributo
|
Attribute
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
Atributo
|
Attribute
|
||||||
(la excepción)
|
(the exception)
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
<code-example path="template-syntax/src/app/app.component.html" region="attribute-binding-syntax-1"></code-example>
|
<code-example path="template-syntax/src/app/app.component.html" region="attribute-binding-syntax-1"></code-example>
|
||||||
@ -283,10 +294,10 @@ La siguiente tabla recoge los objetivos para los diferentes tipos de enlace.
|
|||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td>
|
<td>
|
||||||
Clase
|
Class
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
Propiedad de una <code>clase</code>
|
<code>class</code> property
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
<code-example path="template-syntax/src/app/app.component.html" region="class-binding-syntax-1"></code-example>
|
<code-example path="template-syntax/src/app/app.component.html" region="class-binding-syntax-1"></code-example>
|
||||||
@ -294,13 +305,14 @@ La siguiente tabla recoge los objetivos para los diferentes tipos de enlace.
|
|||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td>
|
<td>
|
||||||
Estilos
|
Style
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
Propiedad de un <code>estilo</code>
|
<code>style</code> property
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
<code-example path="template-syntax/src/app/app.component.html" region="style-binding-syntax-1"></code-example>
|
<code-example path="template-syntax/src/app/app.component.html" region="style-binding-syntax-1"></code-example>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
</table>
|
</table>
|
||||||
|
|
||||||
|
@ -20,7 +20,7 @@ Las funciones que controlan secuencias de animación complejas son las siguiente
|
|||||||
|
|
||||||
{@a complex-sequence}
|
{@a complex-sequence}
|
||||||
|
|
||||||
## Animar varios elementos usando las funciones query() y stagger()
|
## Animar varios elementos usando las funciones query() y stagger()
|
||||||
|
|
||||||
La función `query()` permite encontrar elementos internos dentro del elemento que estás animando. Esta función se dirige a elementos HTML específicos dentro de un componente principal y aplica animaciones a cada elemento individualmente. Angular maneja de manera inteligente la configuración, el desmontaje y la limpieza a medida que coordina los elementos en la página.
|
La función `query()` permite encontrar elementos internos dentro del elemento que estás animando. Esta función se dirige a elementos HTML específicos dentro de un componente principal y aplica animaciones a cada elemento individualmente. Angular maneja de manera inteligente la configuración, el desmontaje y la limpieza a medida que coordina los elementos en la página.
|
||||||
|
|
||||||
|
@ -1,245 +0,0 @@
|
|||||||
# Creating libraries
|
|
||||||
|
|
||||||
This page provides a conceptual overview of how you can create and publish new libraries to extend Angular functionality.
|
|
||||||
|
|
||||||
If you find that you need to solve the same problem in more than one app (or want to share your solution with other developers), you have a candidate for a library.
|
|
||||||
A simple example might be a button that sends users to your company website, that would be included in all apps that your company builds.
|
|
||||||
|
|
||||||
## Getting started
|
|
||||||
|
|
||||||
Use the Angular CLI to generate a new library skeleton in a new workspace with the following commands.
|
|
||||||
|
|
||||||
<code-example language="bash">
|
|
||||||
ng new my-workspace --create-application=false
|
|
||||||
cd my-workspace
|
|
||||||
ng generate library my-lib
|
|
||||||
</code-example>
|
|
||||||
|
|
||||||
The `ng generate` command creates the `projects/my-lib` folder in your workspace, which contains a component and a service inside an NgModule.
|
|
||||||
|
|
||||||
<div class="alert is-helpful">
|
|
||||||
|
|
||||||
For more details on how a library project is structured, refer to the [Library project files](guide/file-structure#library-project-files) section of the [Project File Structure guide](guide/file-structure).
|
|
||||||
|
|
||||||
You can use the monorepo model to use the same workspace for multiple projects.
|
|
||||||
See [Setting up for a multi-project workspace](guide/file-structure#multiple-projects).
|
|
||||||
|
|
||||||
</div>
|
|
||||||
|
|
||||||
When you generate a new library, the workspace configuration file, `angular.json`, is updated with a project of type 'library'.
|
|
||||||
|
|
||||||
<code-example format="json">
|
|
||||||
"projects": {
|
|
||||||
...
|
|
||||||
"my-lib": {
|
|
||||||
"root": "projects/my-lib",
|
|
||||||
"sourceRoot": "projects/my-lib/src",
|
|
||||||
"projectType": "library",
|
|
||||||
"prefix": "lib",
|
|
||||||
"architect": {
|
|
||||||
"build": {
|
|
||||||
"builder": "@angular-devkit/build-ng-packagr:build",
|
|
||||||
...
|
|
||||||
</code-example>
|
|
||||||
|
|
||||||
You can build, test, and lint the project with CLI commands:
|
|
||||||
|
|
||||||
<code-example language="bash">
|
|
||||||
ng build my-lib
|
|
||||||
ng test my-lib
|
|
||||||
ng lint my-lib
|
|
||||||
</code-example>
|
|
||||||
|
|
||||||
Notice that the configured builder for the project is different from the default builder for app projects.
|
|
||||||
This builder, among other things, ensures that the library is always built with the [AOT compiler](guide/aot-compiler), without the need to specify the `--prod` flag.
|
|
||||||
|
|
||||||
To make library code reusable you must define a public API for it. This "user layer" defines what is available to consumers of your library. A user of your library should be able to access public functionality (such as NgModules, service providers and general utility functions) through a single import path.
|
|
||||||
|
|
||||||
The public API for your library is maintained in the `public-api.ts` file in your library folder.
|
|
||||||
Anything exported from this file is made public when your library is imported into an application.
|
|
||||||
Use an NgModule to expose services and components.
|
|
||||||
|
|
||||||
Your library should supply documentation (typically a README file) for installation and maintenance.
|
|
||||||
|
|
||||||
## Refactoring parts of an app into a library
|
|
||||||
|
|
||||||
To make your solution reusable, you need to adjust it so that it does not depend on app-specific code.
|
|
||||||
Here are some things to consider in migrating application functionality to a library.
|
|
||||||
|
|
||||||
* Declarations such as components and pipes should be designed as stateless, meaning they don’t rely on or alter external variables. If you do rely on state, you need to evaluate every case and decide whether it is application state or state that the library would manage.
|
|
||||||
|
|
||||||
* Any observables that the components subscribe to internally should be cleaned up and disposed of during the lifecycle of those components.
|
|
||||||
|
|
||||||
* Components should expose their interactions through inputs for providing context, and outputs for communicating events to other components.
|
|
||||||
|
|
||||||
* Check all internal dependencies.
|
|
||||||
* For custom classes or interfaces used in components or service, check whether they depend on additional classes or interfaces that also need to be migrated.
|
|
||||||
* Similarly, if your library code depends on a service, that service needs to be migrated.
|
|
||||||
* If your library code or its templates depend on other libraries (such as Angular Material, for instance), you must configure your library with those dependencies.
|
|
||||||
|
|
||||||
* Consider how you provide services to client applications.
|
|
||||||
|
|
||||||
* Services should declare their own providers (rather than declaring providers in the NgModule or a component), so that they are *tree-shakable*. This allows the compiler to leave the service out of the bundle if it never gets injected into the application that imports the library. For more about this, see [Tree-shakable providers](guide/dependency-injection-providers#tree-shakable-providers).
|
|
||||||
|
|
||||||
* If you register global service providers or share providers across multiple NgModules, use the [`forRoot()` and `forChild()` design patterns](guide/singleton-services) provided by the [RouterModule](api/router/RouterModule).
|
|
||||||
|
|
||||||
* If your library provides optional services that might not be used by all client applications, support proper tree-shaking for that case by using the [lightweight token design pattern](guide/lightweight-injection-tokens).
|
|
||||||
|
|
||||||
{@a integrating-with-the-cli}
|
|
||||||
|
|
||||||
## Integrating with the CLI using code-generation schematics
|
|
||||||
|
|
||||||
A library typically includes *reusable code* that defines components, services, and other Angular artifacts (pipes, directives, and so on) that you simply import into a project.
|
|
||||||
A library is packaged into an npm package for publishing and sharing.
|
|
||||||
This package can also include [schematics](guide/glossary#schematic) that provide instructions for generating or transforming code directly in your project, in the same way that the CLI creates a generic new component with `ng generate component`.
|
|
||||||
A schematic that is packaged with a library can, for example, provide the Angular CLI with the information it needs to generate a component that configures and uses a particular feature, or set of features, defined in that library.
|
|
||||||
One example of this is Angular Material's navigation schematic which configures the CDK's `BreakpointObserver` and uses it with Material's `MatSideNav` and `MatToolbar` components.
|
|
||||||
|
|
||||||
You can create and include the following kinds of schematics.
|
|
||||||
|
|
||||||
* Include an installation schematic so that `ng add` can add your library to a project.
|
|
||||||
|
|
||||||
* Include generation schematics in your library so that `ng generate` can scaffold your defined artifacts (components, services, tests, and so on) in a project.
|
|
||||||
|
|
||||||
* Include an update schematic so that `ng update` can update your library’s dependencies and provide migrations for breaking changes in new releases.
|
|
||||||
|
|
||||||
What you include in your library depends on your task.
|
|
||||||
For example, you could define a schematic to create a dropdown that is pre-populated with canned data to show how to add it to an app.
|
|
||||||
If you want a dropdown that would contain different passed-in values each time, your library could define a schematic to create it with a given configuration. Developers could then use `ng generate` to configure an instance for their own app.
|
|
||||||
|
|
||||||
Suppose you want to read a configuration file and then generate a form based on that configuration.
|
|
||||||
If that form will need additional customization by the developer who is using your library, it might work best as a schematic.
|
|
||||||
However, if the forms will always be the same and not need much customization by developers, then you could create a dynamic component that takes the configuration and generates the form.
|
|
||||||
In general, the more complex the customization, the more useful the schematic approach.
|
|
||||||
|
|
||||||
To learn more, see [Schematics Overview](guide/schematics) and [Schematics for Libraries](guide/schematics-for-libraries).
|
|
||||||
|
|
||||||
## Publishing your library
|
|
||||||
|
|
||||||
Use the Angular CLI and the npm package manager to build and publish your library as an npm package.
|
|
||||||
|
|
||||||
Before publishing a library to NPM, build it using the `--prod` flag which will use the older compiler and runtime known as View Engine instead of Ivy.
|
|
||||||
|
|
||||||
<code-example language="bash">
|
|
||||||
ng build my-lib --prod
|
|
||||||
cd dist/my-lib
|
|
||||||
npm publish
|
|
||||||
</code-example>
|
|
||||||
|
|
||||||
If you've never published a package in npm before, you must create a user account. Read more in [Publishing npm Packages](https://docs.npmjs.com/getting-started/publishing-npm-packages).
|
|
||||||
|
|
||||||
<div class="alert is-important">
|
|
||||||
|
|
||||||
For now, it is not recommended to publish Ivy libraries to NPM because Ivy generated code is not backward compatible with View Engine, so apps using View Engine will not be able to consume them. Furthermore, the internal Ivy instructions are not yet stable, which can potentially break consumers using a different Angular version from the one used to build the library.
|
|
||||||
|
|
||||||
When a published library is used in an Ivy app, the Angular CLI will automatically convert it to Ivy using a tool known as the Angular compatibility compiler (`ngcc`). Thus, publishing your libraries using the View Engine compiler ensures that they can be transparently consumed by both View Engine and Ivy apps.
|
|
||||||
|
|
||||||
</div>
|
|
||||||
|
|
||||||
{@a lib-assets}
|
|
||||||
|
|
||||||
## Managing assets in a library
|
|
||||||
|
|
||||||
Starting with version 9.x of the [ng-packagr](https://github.com/ng-packagr/ng-packagr/blob/master/README.md) tool, you can configure the tool to automatically copy assets into your library package as part of the build process.
|
|
||||||
You can use this feature when your library needs to publish optional theming files, Sass mixins, or documentation (like a changelog).
|
|
||||||
|
|
||||||
* Learn how to [copy assets into your library as part of the build](https://github.com/ng-packagr/ng-packagr/blob/master/docs/copy-assets.md).
|
|
||||||
|
|
||||||
* Learn more about how to use the tool to [embed assets in CSS](https://github.com/ng-packagr/ng-packagr/blob/master/docs/embed-assets-css.md).
|
|
||||||
|
|
||||||
|
|
||||||
## Linked libraries
|
|
||||||
|
|
||||||
While working on a published library, you can use [npm link](https://docs.npmjs.com/cli/link) to avoid reinstalling the library on every build.
|
|
||||||
|
|
||||||
The library must be rebuilt on every change.
|
|
||||||
When linking a library, make sure that the build step runs in watch mode, and that the library's `package.json` configuration points at the correct entry points.
|
|
||||||
For example, `main` should point at a JavaScript file, not a TypeScript file.
|
|
||||||
|
|
||||||
## Use TypeScript path mapping for peer dependencies
|
|
||||||
|
|
||||||
Angular libraries should list all `@angular/*` dependencies as peer dependencies.
|
|
||||||
This ensures that when modules ask for Angular, they all get the exact same module.
|
|
||||||
If a library lists `@angular/core` in `dependencies` instead of `peerDependencies`, it might get a different Angular module instead, which would cause your application to break.
|
|
||||||
|
|
||||||
While developing a library, you must install all peer dependencies through `devDependencies` to ensure that the library compiles properly.
|
|
||||||
A linked library will then have its own set of Angular libraries that it uses for building, located in its `node_modules` folder.
|
|
||||||
However, this can cause problems while building or running your application.
|
|
||||||
|
|
||||||
To get around this problem you can use TypeScript path mapping to tell TypeScript that it should load some modules from a specific location.
|
|
||||||
List all the peer dependencies that your library uses in the workspace TypeScript configuration file `./tsconfig.json`, and point them at the local copy in the app's `node_modules` folder.
|
|
||||||
|
|
||||||
```
|
|
||||||
{
|
|
||||||
"compilerOptions": {
|
|
||||||
// ...
|
|
||||||
// paths are relative to `baseUrl` path.
|
|
||||||
"paths": {
|
|
||||||
"@angular/*": [
|
|
||||||
"./node_modules/@angular/*"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
This mapping ensures that your library always loads the local copies of the modules it needs.
|
|
||||||
|
|
||||||
|
|
||||||
## Using your own library in apps
|
|
||||||
|
|
||||||
You don't have to publish your library to the npm package manager in order to use it in your own apps, but you do have to build it first.
|
|
||||||
|
|
||||||
To use your own library in an app:
|
|
||||||
|
|
||||||
* Build the library. You cannot use a library before it is built.
|
|
||||||
<code-example language="bash">
|
|
||||||
ng build my-lib
|
|
||||||
</code-example>
|
|
||||||
|
|
||||||
* In your apps, import from the library by name:
|
|
||||||
```
|
|
||||||
import { myExport } from 'my-lib';
|
|
||||||
```
|
|
||||||
|
|
||||||
### Building and rebuilding your library
|
|
||||||
|
|
||||||
The build step is important if you haven't published your library as an npm package and then installed the package back into your app from npm.
|
|
||||||
For instance, if you clone your git repository and run `npm install`, your editor will show the `my-lib` imports as missing if you haven't yet built your library.
|
|
||||||
|
|
||||||
<div class="alert is-helpful">
|
|
||||||
|
|
||||||
When you import something from a library in an Angular app, Angular looks for a mapping between the library name and a location on disk.
|
|
||||||
When you install a library package, the mapping is in the `node_modules` folder. When you build your own library, it has to find the mapping in your `tsconfig` paths.
|
|
||||||
|
|
||||||
Generating a library with the Angular CLI automatically adds its path to the `tsconfig` file.
|
|
||||||
The Angular CLI uses the `tsconfig` paths to tell the build system where to find the library.
|
|
||||||
|
|
||||||
</div>
|
|
||||||
|
|
||||||
If you find that changes to your library are not reflected in your app, your app is probably using an old build of the library.
|
|
||||||
|
|
||||||
You can rebuild your library whenever you make changes to it, but this extra step takes time.
|
|
||||||
*Incremental builds* functionality improves the library-development experience.
|
|
||||||
Every time a file is changed a partial build is performed that emits the amended files.
|
|
||||||
|
|
||||||
Incremental builds can be run as a background process in your dev environment. To take advantage of this feature add the `--watch` flag to the build command:
|
|
||||||
|
|
||||||
<code-example language="bash">
|
|
||||||
ng build my-lib --watch
|
|
||||||
</code-example>
|
|
||||||
|
|
||||||
<div class="alert is-important">
|
|
||||||
|
|
||||||
The CLI `build` command uses a different builder and invokes a different build tool for libraries than it does for applications.
|
|
||||||
|
|
||||||
* The build system for apps, `@angular-devkit/build-angular`, is based on `webpack`, and is included in all new Angular CLI projects.
|
|
||||||
* The build system for libraries is based on `ng-packagr`. It is only added to your dependencies when you add a library using `ng generate library my-lib`.
|
|
||||||
|
|
||||||
The two build systems support different things, and even where they support the same things, they do those things differently.
|
|
||||||
This means that the TypeScript source can result in different JavaScript code in a built library than it would in a built application.
|
|
||||||
|
|
||||||
For this reason, an app that depends on a library should only use TypeScript path mappings that point to the *built library*.
|
|
||||||
TypeScript path mappings should *not* point to the library source `.ts` files.
|
|
||||||
|
|
||||||
</div>
|
|
247
aio/content/guide/creating-libraries.es.md
Normal file
247
aio/content/guide/creating-libraries.es.md
Normal file
@ -0,0 +1,247 @@
|
|||||||
|
# Creando librerías
|
||||||
|
|
||||||
|
Está pagina provee una vista conceptual de como puedes crear y publicar nuevas librerías para extender las funcionalidades de Angular.
|
||||||
|
|
||||||
|
Si necesitas resolver el mismo problema en mas de una aplicación (o quiere compartir tu solución con otros desarrolladores), tienes un candidato para una librería.
|
||||||
|
Un ejemplo simple puede ser un botón que envía a los usuarios hacia el sitio web de tu empresa, que sería incluido en todas las aplicaciones que tu empresa crea.
|
||||||
|
|
||||||
|
## Empezando
|
||||||
|
|
||||||
|
Usa el Angular CLI para generar un nuevo esqueleto de librería, en nuevo espacio de trabajo con los siguiente comandos.
|
||||||
|
|
||||||
|
<code-example language="bash">
|
||||||
|
ng new my-workspace --create-application=false
|
||||||
|
cd my-workspace
|
||||||
|
ng generate library my-lib
|
||||||
|
</code-example>
|
||||||
|
|
||||||
|
El comando `ng generate` crea la carpeta `projects/my-lib` en el espacio de trabajo, que contiene un componente y un servicio dentro de un NgModule.
|
||||||
|
|
||||||
|
<div class="alert is-helpful">
|
||||||
|
|
||||||
|
Para más detalles sobre como una librería es estructurada, refiérase a los [Archivos de Librería](guide/file-structure#library-project-files) en la sección de [Guía de estructura de archivos](guide/file-structure).
|
||||||
|
|
||||||
|
Puedes usar un modelo de monorepo para usar el mismo espacio de trabajo con multiples proyectos. Véase [Configuración para espacio de trabajo multiproyecto](guide/file-structure#multiple-projects).
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
Cuando se genera una nueva librería, el archivo de configuración del espacio de trabajo, `angular.json`, es actualizado con un proyecto de tipo 'library'.
|
||||||
|
|
||||||
|
<code-example format="json">
|
||||||
|
"projects": {
|
||||||
|
...
|
||||||
|
"my-lib": {
|
||||||
|
"root": "projects/my-lib",
|
||||||
|
"sourceRoot": "projects/my-lib/src",
|
||||||
|
"projectType": "library",
|
||||||
|
"prefix": "lib",
|
||||||
|
"architect": {
|
||||||
|
"build": {
|
||||||
|
"builder": "@angular-devkit/build-ng-packagr:build",
|
||||||
|
...
|
||||||
|
</code-example>
|
||||||
|
|
||||||
|
Puedes crear, probar y comprobar con los comandos de CLI:
|
||||||
|
|
||||||
|
<code-example language="bash">
|
||||||
|
ng build my-lib
|
||||||
|
ng test my-lib
|
||||||
|
ng lint my-lib
|
||||||
|
</code-example>
|
||||||
|
|
||||||
|
Puedes notar que el constructor configurado para el proyecto es diferente que el constructor por defecto para proyectos.
|
||||||
|
El constructor, entre otras cosas, asegura que la librería siempre este construida con el [compilador AOT](guide/aot-compiler), sin la necesidad de especificar la bandera `--prod`.
|
||||||
|
|
||||||
|
Para hacer el código de la librería reusable debes definir una API pública para ella. Esta "capa de usuario" define que esta disponible para los consumidores de tu librería. Un usuario de tu librería debería ser capaz de acceder a la funcionalidad publica (como NgModules, servicios, proveedores y en general funciones de utilidad) mediante una sola ruta.
|
||||||
|
|
||||||
|
La API pública para tu librería es mantenida en el archivo `public-api.ts` en tu carpeta de librería.
|
||||||
|
Cualquier cosa exportada desde este archivo se hace publica cuando tu librería es importada dentro de una aplicación.
|
||||||
|
Usa un NgModule para exponer los servicios y componentes.
|
||||||
|
|
||||||
|
Tu libería debería suministrar documentatión (típicamente en el archivo README) para la instalación y mantenimiento.
|
||||||
|
|
||||||
|
## Refactorizando partes de una app dentro de un librería
|
||||||
|
|
||||||
|
Para hacer tu solución reusable, necesitas ajustarla para que no dependa del código específico de la aplicación.
|
||||||
|
Aquí algunas cosas para considerar al migrar la funcionalidad de la aplicación a una librería.
|
||||||
|
|
||||||
|
* Declaraciones tales como componentes y pipes deberían ser diseñados como 'stateless' (sin estado), lo que significa que no dependen ni alteran variables externas. Si tu dependes del estado, necesitas evaluar cada caso y decidir el estado de la aplicación o el estado que la aplicación administraría.
|
||||||
|
|
||||||
|
* Cualquier observable al cual los componentes se suscriban internamente deberían ser limpiados y desechados durante el ciclo de vida de esos componentes.
|
||||||
|
|
||||||
|
* Los componentes deberían exponer sus interacciones a través de 'inputs' para proporcionar contexto y 'outputs' para comunicar los eventos hacia otros componentes.
|
||||||
|
|
||||||
|
* Verifique todas las dependencias internas.
|
||||||
|
* Para clases personalizadas o interfaces usadas en componentes o servicios, verifique si dependen en clases adicionales o interfaces que también necesiten ser migradas.
|
||||||
|
* Del mismo modo, si tu código de librería depende de un servicio, este servicio necesita ser migrado.
|
||||||
|
* Si tu código de librería o sus plantillas dependen de otras librerías (como Angular Material), debes configurar tu librería con esas dependencias.
|
||||||
|
|
||||||
|
* Considere como proporcionar servicios a las aplicaciones cliente.
|
||||||
|
|
||||||
|
* Los servicios deberían declarar sus propios proveedores (en lugar de declarar los proveedores en el NgModule o en un componente). Esto le permite al compilador dejar los servicios fuera del 'bundle' si este nunca fue inyectado dentro de la aplicación que importa la librería, véase [proveedores Tree-shakable](guide/dependency-injection-providers#tree-shakable-providers)
|
||||||
|
* Si registras proveedores globales o compartes proveedores a través de múltiples NgModules, usa el [`forRoot()` y `forChild()` como patrones de diseño](guide/singleton-services) proporcionados por el [RouterModule](api/router/RouterModule).
|
||||||
|
* Si tu librería proporciona servicios opcionales que podrían no ser usados por todos las aplicaciones cliente, soporte apropiadamente el 'tree-shaking' para esos casos usando el [patrón de diseño de token ligero](guide/lightweight-injection-tokens).
|
||||||
|
|
||||||
|
{@a integrating-with-the-cli}
|
||||||
|
|
||||||
|
## Integración con el CLI usando generación de código con los schematics.
|
||||||
|
|
||||||
|
Comúnmente una librería incluye *código reusable* que define componentes, servicios y otros Artefactos de Angular (pipes, directivas y etc.) que tu simplemente importas a un proyecto.
|
||||||
|
Una librería es empaquetada dentro de un paquete npm para publicar y compartir.
|
||||||
|
|
||||||
|
Este paquete también puede incluir [schematics](guide/glossary#schematic) que proporciona instrucciones para generar o transformar código directamente un tu proyecto, de la misma forma que el CLI crea un nuevo componente genérico con `ng generate component`.
|
||||||
|
|
||||||
|
Un 'schematic' empaquetado con una librería puede por ejemplo proporcionar al Angular CLI la información que necesita para generar un componente que configura y usa una particular característica o conjunto de características, definido en la librería.
|
||||||
|
|
||||||
|
Un ejemplo de esto es el 'schematic' de navegación de Angular Material el cual configura los CDK's `BreakpointObserver` y lo usa con los componentes `MatSideNav` y `MatToolbar` de Angular Material.
|
||||||
|
|
||||||
|
Puedes crear e incluir los siguientes tipos de 'schematics'.
|
||||||
|
|
||||||
|
* Incluye un 'schematic' de instalación para que con `ng add` puedas agregar tu libería a un proyecto.
|
||||||
|
|
||||||
|
* Incluye un 'schematic' de generación en tu librería para que con `ng generate` puedas hacer scaffolding de sus artefactos (componentes, servicios, pruebas y etc) en un proyecto.
|
||||||
|
|
||||||
|
* Incluye un 'schematic' de actualización para que con `ng update` puedas actualizar las dependencias de tu librería y proporcionar migraciones para cambios importantes en un nuevo release.
|
||||||
|
|
||||||
|
Lo que incluya tu librería depende de tu tarea.
|
||||||
|
Por ejemplo, podrías definir un 'schematic' para crear un desplegable (dropdown) que esta pre-poblado con datos para mostrar como agregarlo a una aplicación.
|
||||||
|
Si quieres un desplegable (dropdown) que contendrá valores diferentes cada vez, tu librería podría definir un 'schematic' para crearlo con una configuración dada. Los desarrolladores podrán entonces usar `ng generate` para configurar una instancia para sus propias aplicaciones.
|
||||||
|
|
||||||
|
Supón que quieres leer un archivo de configuración y entonces generar una formulario con base a la configuración.
|
||||||
|
Si este formulario necesita personalización adicional por parte del desarrollador que esta usando tu librería, esto podría trabajar mejor como un 'schematic'.
|
||||||
|
Sin embargo, si el formulario siempre será el mismo y no necesita de mucha personalización por parte de los desarrolladores, entonces podría crear un componente dinámico que tome la configuración y genere el formulario.
|
||||||
|
En general, entre más compleja sea personalización, la más util será en enfoque de un 'schematic'.
|
||||||
|
|
||||||
|
Para aprender más, véase [Vista general de Schematics](guide/schematics)
|
||||||
|
|
||||||
|
## Publicando tu librería
|
||||||
|
|
||||||
|
Usa el Angular CLI y el gestor de paquetes npm para construir y publicar tu librería como un paquete npm.
|
||||||
|
|
||||||
|
Antes de publicar una librería a NPM, constrúyela usando la bandera `--prod` la cúal usará el compilador y tiempo de ejecución (runtime) más antiguos como 'View Engine' en vez de 'Ivy'.
|
||||||
|
|
||||||
|
<code-example language="bash">
|
||||||
|
ng build my-lib --prod
|
||||||
|
cd dist/my-lib
|
||||||
|
npm publish
|
||||||
|
</code-example>
|
||||||
|
|
||||||
|
Si nunca has publicado un paquete en npm antes, tu debes crear un cuenta. Lee más en [Publicando paquetes npm](https://docs.npmjs.com/getting-started/publishing-npm-packages).
|
||||||
|
|
||||||
|
<div class="alert is-important">
|
||||||
|
|
||||||
|
Por ahora, no es recomendando publicar librerías con Ivy hacia NPM por que Ivy genera código que no es retrocompatible con 'View Engine', entonces las aplicaciones usando 'View Engine' no podrán consumirlas. Además, las instrucciones internas de IVY no son estables aun, lo cual puede romper potencialmente a los consumidores que usan una diferente versión de Angular a la que uso para construir la libería.
|
||||||
|
|
||||||
|
Cuando una librería publicada es usada en una aplicación con Ivy, el Angular CLI automáticamente la convertirá a Ivy usando una herramienta conocida como el compilador de compatibilidad Angular (`ngcc`). Por lo tanto, publicar tus librerías usado el compilador 'View Engine' garantiza que ellas puede ser consumidas de forma transparente por ambos motores 'View Engine' y 'Ivy'.
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{@a lib-assets}
|
||||||
|
|
||||||
|
## Gestionando activos (assets) en una librería.
|
||||||
|
|
||||||
|
Desde la versión 9.x de la herramienta [ng-packagr](https://github.com/ng-packagr/ng-packagr/blob/master/README.md), puedes configurar la herramienta para que automáticamente copie los activos (assets) dentro de el paquete de librería como parte del proceso de construcción.
|
||||||
|
Puedes usar esta característica cuando tu librería necesite publicar archivos de temas opcionales, funciones de Sass o documentación (como un registro de cambios 'changelog').
|
||||||
|
|
||||||
|
* Aprende como [copiar activos (assets) dentro de tu librería como parte de la construcción](https://github.com/ng-packagr/ng-packagr/blob/master/docs/copy-assets.md).
|
||||||
|
|
||||||
|
* Aprende más acerca de como usar la herramienta para [incrustar activos (assets) de CSS](https://github.com/ng-packagr/ng-packagr/blob/master/docs/embed-assets-css.md).
|
||||||
|
|
||||||
|
|
||||||
|
## Vinculando librerías
|
||||||
|
|
||||||
|
Mientras trabajas en un librería publicada, puedes usar [npm link](https://docs.npmjs.com/cli/link) para evitar re instalar la librería en cada construcción.
|
||||||
|
|
||||||
|
La librería debe ser reconstruida en cada cambio.
|
||||||
|
Cuando vinculas una librería, asegurate que el paso de construir corra en modo vigía (watch mode) y que el `package.json` de la librería configure los puntos de entrada correctos.
|
||||||
|
Por ejemplo, `main` debería apuntar a un archivo JavaScript, no a un archivo TypeScript.
|
||||||
|
|
||||||
|
## Utiliza el mapeo de rutas de TypeScript por las dependencias de pares.
|
||||||
|
|
||||||
|
Las librerías de Angular deben enumerar todas las dependencias `@angular/*` como dependencias de pares.
|
||||||
|
Esto garantiza que cuando los módulos solicitan Angular, todos ellos obtienen exactamente el mismo módulo.
|
||||||
|
Si tu librería lista `@angular/core` en `dependencies` en vez de en `peerDependencies`, podría obtener un módulo Angular diferente, lo qué haría que tu aplicación se rompiera.
|
||||||
|
|
||||||
|
Cuando desarrollas una librería, tu debes instalar todas las dependencias de pares mediante `devDependencies` para garantizar que la librería compile apropiadamente.
|
||||||
|
Una librería vinculada tendrá su propio conjunto de librerías Angular que usa para construir, ubicados en su carpeta `node_modules`.
|
||||||
|
|
||||||
|
Sin embargo, esto puede causar problemas mientras construyes o corres tu aplicación.
|
||||||
|
|
||||||
|
Para evitar este problema tu puedes usar el mapeo de rutas de TypeScript para indicarle a TypeScript que este debería cargar algunos módulos desde una ubicación especifica.
|
||||||
|
|
||||||
|
Enumera todas las dependencias de pares que tu librería usa en el archivo de configuración `./tsconfig.json` del espacio de trabajo de TypeScript, y apúntalos a la copia local en la carpeta `node_modules` de la aplicación.
|
||||||
|
|
||||||
|
```
|
||||||
|
{
|
||||||
|
"compilerOptions": {
|
||||||
|
// ...
|
||||||
|
// paths are relative to `baseUrl` path.
|
||||||
|
"paths": {
|
||||||
|
"@angular/*": [
|
||||||
|
"./node_modules/@angular/*"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Este mapeador garantiza que tu librería siempre cargue las copias locales del módulo que necesita.
|
||||||
|
|
||||||
|
|
||||||
|
## Usando tu propia librería en aplicaciones.
|
||||||
|
|
||||||
|
No tienes que publicar tu librería hacia el gestor de paquetes npm para usarla en tus propias aplicaciones, pero tienes que construirla primero.
|
||||||
|
|
||||||
|
Para usar tu propia librería en tu aplicación:
|
||||||
|
|
||||||
|
* Construye la librería. No puedes usar una librería antes que se construya.
|
||||||
|
<code-example language="bash">
|
||||||
|
ng build my-lib
|
||||||
|
</code-example>
|
||||||
|
|
||||||
|
* En tus aplicaciones, importa la librería por el nombre:
|
||||||
|
```
|
||||||
|
import { myExport } from 'my-lib';
|
||||||
|
```
|
||||||
|
|
||||||
|
### Construyendo y re construyendo tu librería.
|
||||||
|
|
||||||
|
El paso de construir es importante si no tienes publicada tu librería como un paquete npm y luego ha instalado el paquete de nuevo dentro tu aplicación desde npm.
|
||||||
|
Por ejemplo, si clonas tu repositorio git y corres `npm install`, tu editor mostrará la importación de `my-lib` como perdida si no tienes aun construida tu librería.
|
||||||
|
|
||||||
|
<div class="alert is-helpful">
|
||||||
|
|
||||||
|
Cuando importas algo desde una librería en una aplicación Angular, Angular busca un mapeo entre el nombre de librería y una ubicación en disco.
|
||||||
|
Cuando instalas un paquete de librería, el mapeo esta en la carpeta `node_modules`. Cuando construyes tu propia librería, tiene que encontrar el mapeo en tus rutas de `tsconfig`.
|
||||||
|
|
||||||
|
Generando una librería con el Angular CLI automáticamente agrega su ruta en el archivo `tsconfig`.
|
||||||
|
El Angular CLI usa las rutas `tsconfig` para indicarle al sistema construido donde encontrar la librería.
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
Si descubres que los cambios en tu librería no son reflejados en tu aplicación, tu aplicación probablemente esta usando una construcción antigua de la librería.
|
||||||
|
|
||||||
|
Puedes re construir tu librería cada vez que hagas cambios en esta, pero este paso extra toma tiempo.
|
||||||
|
Las *construcciones incrementales* funcionalmente mejoran la experiencia de desarrollo de librerías.
|
||||||
|
Cada vez que un archivo es cambiando una construcción parcial es realizada y esta emite los archivos modificados.
|
||||||
|
|
||||||
|
Las *Construcciones incrementales* puede ser ejecutadas como un proceso en segundo plano en tu entorno de desarrollo. Para aprovechar esta característica agrega la bandera `--watch` al comando de construcción:
|
||||||
|
|
||||||
|
<code-example language="bash">
|
||||||
|
ng build my-lib --watch
|
||||||
|
</code-example>
|
||||||
|
|
||||||
|
<div class="alert is-important">
|
||||||
|
|
||||||
|
El comando `build` del CLI utiliza un constructor diferente e invoca una herramienta de construcción diferente para las librerías que para las aplicaciones.
|
||||||
|
|
||||||
|
* El sistema de construcción para aplicaciones, `@angular-devkit/build-angular`, esta basado en `webpack`, y esta incluida en todos los nuevos proyectos de Angular CLI.
|
||||||
|
* El sistema de construcción esta basado en `ng-packagr`. Este es solo agregado en tus dependencias cuando agregas una librería usando `ng generate library my-lib`.
|
||||||
|
|
||||||
|
Los dos sistemas de construcción soportan diferentes cosas e incluso si ellos soportan las mismas cosas, ellos hacen esas cosas de forma diferente.
|
||||||
|
Esto quiere decir que la fuente de TypeScript puede generar en código JavaScript diferente en una librería construida que en una aplicación construida.
|
||||||
|
|
||||||
|
Por esta razón, una aplicación que depende de una librería debería solo usar el mapeo de rutas de TypeScript que apunte a la *librería construida*.
|
||||||
|
El mapeo de rutas de TypeScript no debería apuntar hacia los archivos `.ts` fuente de la librería.
|
||||||
|
|
||||||
|
</div>
|
@ -1,13 +1,13 @@
|
|||||||
# Creando librerías
|
# Creating libraries
|
||||||
|
|
||||||
Está pagina provee una vista conceptual de como puedes crear y publicar nuevas librerías para extender las funcionalidades de Angular.
|
This page provides a conceptual overview of how you can create and publish new libraries to extend Angular functionality.
|
||||||
|
|
||||||
Si necesitas resolver el mismo problema en mas de una aplicación (o quiere compartir tu solución con otros desarrolladores), tienes un candidato para una librería.
|
If you find that you need to solve the same problem in more than one app (or want to share your solution with other developers), you have a candidate for a library.
|
||||||
Un ejemplo simple puede ser un botón que envía a los usuarios hacia el sitio web de tu empresa, que sería incluido en todas las aplicaciones que tu empresa crea.
|
A simple example might be a button that sends users to your company website, that would be included in all apps that your company builds.
|
||||||
|
|
||||||
## Empezando
|
## Getting started
|
||||||
|
|
||||||
Usa el Angular CLI para generar un nuevo esqueleto de librería, en nuevo espacio de trabajo con los siguiente comandos.
|
Use the Angular CLI to generate a new library skeleton in a new workspace with the following commands.
|
||||||
|
|
||||||
<code-example language="bash">
|
<code-example language="bash">
|
||||||
ng new my-workspace --create-application=false
|
ng new my-workspace --create-application=false
|
||||||
@ -15,17 +15,18 @@ Usa el Angular CLI para generar un nuevo esqueleto de librería, en nuevo espaci
|
|||||||
ng generate library my-lib
|
ng generate library my-lib
|
||||||
</code-example>
|
</code-example>
|
||||||
|
|
||||||
El comando `ng generate` crea la carpeta `projects/my-lib` en el espacio de trabajo, que contiene un componente y un servicio dentro de un NgModule.
|
The `ng generate` command creates the `projects/my-lib` folder in your workspace, which contains a component and a service inside an NgModule.
|
||||||
|
|
||||||
<div class="alert is-helpful">
|
<div class="alert is-helpful">
|
||||||
|
|
||||||
Para más detalles sobre como una librería es estructurada, refiérase a los [Archivos de Librería](guide/file-structure#library-project-files) en la sección de [Guía de estructura de archivos](guide/file-structure).
|
For more details on how a library project is structured, refer to the [Library project files](guide/file-structure#library-project-files) section of the [Project File Structure guide](guide/file-structure).
|
||||||
|
|
||||||
Puedes usar un modelo de monorepo para usar el mismo espacio de trabajo con multiples proyectos. Véase [Configuración para espacio de trabajo multiproyecto](guide/file-structure#multiple-projects).
|
You can use the monorepo model to use the same workspace for multiple projects.
|
||||||
|
See [Setting up for a multi-project workspace](guide/file-structure#multiple-projects).
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
Cuando se genera una nueva librería, el archivo de configuración del espacio de trabajo, `angular.json`, es actualizado con un proyecto de tipo 'library'.
|
When you generate a new library, the workspace configuration file, `angular.json`, is updated with a project of type 'library'.
|
||||||
|
|
||||||
<code-example format="json">
|
<code-example format="json">
|
||||||
"projects": {
|
"projects": {
|
||||||
@ -41,7 +42,7 @@ Cuando se genera una nueva librería, el archivo de configuración del espacio d
|
|||||||
...
|
...
|
||||||
</code-example>
|
</code-example>
|
||||||
|
|
||||||
Puedes crear, probar y comprobar con los comandos de CLI:
|
You can build, test, and lint the project with CLI commands:
|
||||||
|
|
||||||
<code-example language="bash">
|
<code-example language="bash">
|
||||||
ng build my-lib
|
ng build my-lib
|
||||||
@ -49,78 +50,75 @@ Puedes crear, probar y comprobar con los comandos de CLI:
|
|||||||
ng lint my-lib
|
ng lint my-lib
|
||||||
</code-example>
|
</code-example>
|
||||||
|
|
||||||
Puedes notar que el constructor configurado para el proyecto es diferente que el constructor por defecto para proyectos.
|
Notice that the configured builder for the project is different from the default builder for app projects.
|
||||||
El constructor, entre otras cosas, asegura que la librería siempre este construida con el [compilador AOT](guide/aot-compiler), sin la necesidad de especificar la bandera `--prod`.
|
This builder, among other things, ensures that the library is always built with the [AOT compiler](guide/aot-compiler), without the need to specify the `--prod` flag.
|
||||||
|
|
||||||
Para hacer el código de la librería reusable debes definir una API pública para ella. Esta "capa de usuario" define que esta disponible para los consumidores de tu librería. Un usuario de tu librería debería ser capaz de acceder a la funcionalidad publica (como NgModules, servicios, proveedores y en general funciones de utilidad) mediante una sola ruta.
|
To make library code reusable you must define a public API for it. This "user layer" defines what is available to consumers of your library. A user of your library should be able to access public functionality (such as NgModules, service providers and general utility functions) through a single import path.
|
||||||
|
|
||||||
La API pública para tu librería es mantenida en el archivo `public-api.ts` en tu carpeta de librería.
|
The public API for your library is maintained in the `public-api.ts` file in your library folder.
|
||||||
Cualquier cosa exportada desde este archivo se hace publica cuando tu librería es importada dentro de una aplicación.
|
Anything exported from this file is made public when your library is imported into an application.
|
||||||
Usa un NgModule para exponer los servicios y componentes.
|
Use an NgModule to expose services and components.
|
||||||
|
|
||||||
Tu libería debería suministrar documentatión (típicamente en el archivo README) para la instalación y mantenimiento.
|
Your library should supply documentation (typically a README file) for installation and maintenance.
|
||||||
|
|
||||||
## Refactorizando partes de una app dentro de un librería
|
## Refactoring parts of an app into a library
|
||||||
|
|
||||||
Para hacer tu solución reusable, necesitas ajustarla para que no dependa del código específico de la aplicación.
|
To make your solution reusable, you need to adjust it so that it does not depend on app-specific code.
|
||||||
Aquí algunas cosas para considerar al migrar la funcionalidad de la aplicación a una librería.
|
Here are some things to consider in migrating application functionality to a library.
|
||||||
|
|
||||||
* Declaraciones tales como componentes y pipes deberían ser diseñados como 'stateless' (sin estado), lo que significa que no dependen ni alteran variables externas. Si tu dependes del estado, necesitas evaluar cada caso y decidir el estado de la aplicación o el estado que la aplicación administraría.
|
* Declarations such as components and pipes should be designed as stateless, meaning they don’t rely on or alter external variables. If you do rely on state, you need to evaluate every case and decide whether it is application state or state that the library would manage.
|
||||||
|
|
||||||
* Cualquier observable al cual los componentes se suscriban internamente deberían ser limpiados y desechados durante el ciclo de vida de esos componentes.
|
* Any observables that the components subscribe to internally should be cleaned up and disposed of during the lifecycle of those components.
|
||||||
|
|
||||||
* Los componentes deberían exponer sus interacciones a través de 'inputs' para proporcionar contexto y 'outputs' para comunicar los eventos hacia otros componentes.
|
* Components should expose their interactions through inputs for providing context, and outputs for communicating events to other components.
|
||||||
|
|
||||||
* Verifique todas las dependencias internas.
|
* Check all internal dependencies.
|
||||||
* Para clases personalizadas o interfaces usadas en componentes o servicios, verifique si dependen en clases adicionales o interfaces que también necesiten ser migradas.
|
* For custom classes or interfaces used in components or service, check whether they depend on additional classes or interfaces that also need to be migrated.
|
||||||
* Del mismo modo, si tu código de librería depende de un servicio, este servicio necesita ser migrado.
|
* Similarly, if your library code depends on a service, that service needs to be migrated.
|
||||||
* Si tu código de librería o sus plantillas dependen de otras librerías (como Angular Material), debes configurar tu librería con esas dependencias.
|
* If your library code or its templates depend on other libraries (such as Angular Material, for instance), you must configure your library with those dependencies.
|
||||||
|
|
||||||
* Considere como proporcionar servicios a las aplicaciones cliente.
|
* Consider how you provide services to client applications.
|
||||||
|
|
||||||
* Los servicios deberían declarar sus propios proveedores (en lugar de declarar los proveedores en el NgModule o en un componente). Esto le permite al compilador dejar los servicios fuera del 'bundle' si este nunca fue inyectado dentro de la aplicación que importa la librería, véase [proveedores Tree-shakable](guide/dependency-injection-providers#tree-shakable-providers)
|
* Services should declare their own providers (rather than declaring providers in the NgModule or a component), so that they are *tree-shakable*. This allows the compiler to leave the service out of the bundle if it never gets injected into the application that imports the library. For more about this, see [Tree-shakable providers](guide/dependency-injection-providers#tree-shakable-providers).
|
||||||
* Si registras proveedores globales o compartes proveedores a través de múltiples NgModules, usa el [`forRoot()` y `forChild()` como patrones de diseño](guide/singleton-services) proporcionados por el [RouterModule](api/router/RouterModule).
|
|
||||||
* Si tu librería proporciona servicios opcionales que podrían no ser usados por todos las aplicaciones cliente, soporte apropiadamente el 'tree-shaking' para esos casos usando el [patrón de diseño de token ligero](guide/lightweight-injection-tokens).
|
* If you register global service providers or share providers across multiple NgModules, use the [`forRoot()` and `forChild()` design patterns](guide/singleton-services) provided by the [RouterModule](api/router/RouterModule).
|
||||||
|
|
||||||
|
* If your library provides optional services that might not be used by all client applications, support proper tree-shaking for that case by using the [lightweight token design pattern](guide/lightweight-injection-tokens).
|
||||||
|
|
||||||
{@a integrating-with-the-cli}
|
{@a integrating-with-the-cli}
|
||||||
|
|
||||||
## Integración con el CLI usando generación de código con los schematics.
|
## Integrating with the CLI using code-generation schematics
|
||||||
|
|
||||||
Comúnmente una librería incluye *código reusable* que define componentes, servicios y otros Artefactos de Angular (pipes, directivas y etc.) que tu simplemente importas a un proyecto.
|
A library typically includes *reusable code* that defines components, services, and other Angular artifacts (pipes, directives, and so on) that you simply import into a project.
|
||||||
Una librería es empaquetada dentro de un paquete npm para publicar y compartir.
|
A library is packaged into an npm package for publishing and sharing.
|
||||||
|
This package can also include [schematics](guide/glossary#schematic) that provide instructions for generating or transforming code directly in your project, in the same way that the CLI creates a generic new component with `ng generate component`.
|
||||||
|
A schematic that is packaged with a library can, for example, provide the Angular CLI with the information it needs to generate a component that configures and uses a particular feature, or set of features, defined in that library.
|
||||||
|
One example of this is Angular Material's navigation schematic which configures the CDK's `BreakpointObserver` and uses it with Material's `MatSideNav` and `MatToolbar` components.
|
||||||
|
|
||||||
Este paquete también puede incluir [schematics](guide/glossary#schematic) que proporciona instrucciones para generar o transformar código directamente un tu proyecto, de la misma forma que el CLI crea un nuevo componente genérico con `ng generate component`.
|
You can create and include the following kinds of schematics.
|
||||||
|
|
||||||
Un 'schematic' empaquetado con una librería puede por ejemplo proporcionar al Angular CLI la información que necesita para generar un componente que configura y usa una particular característica o conjunto de características, definido en la librería.
|
* Include an installation schematic so that `ng add` can add your library to a project.
|
||||||
|
|
||||||
Un ejemplo de esto es el 'schematic' de navegación de Angular Material el cual configura los CDK's `BreakpointObserver` y lo usa con los componentes `MatSideNav` y `MatToolbar` de Angular Material.
|
* Include generation schematics in your library so that `ng generate` can scaffold your defined artifacts (components, services, tests, and so on) in a project.
|
||||||
|
|
||||||
Puedes crear e incluir los siguientes tipos de 'schematics'.
|
* Include an update schematic so that `ng update` can update your library’s dependencies and provide migrations for breaking changes in new releases.
|
||||||
|
|
||||||
* Incluye un 'schematic' de instalación para que con `ng add` puedas agregar tu libería a un proyecto.
|
What you include in your library depends on your task.
|
||||||
|
For example, you could define a schematic to create a dropdown that is pre-populated with canned data to show how to add it to an app.
|
||||||
|
If you want a dropdown that would contain different passed-in values each time, your library could define a schematic to create it with a given configuration. Developers could then use `ng generate` to configure an instance for their own app.
|
||||||
|
|
||||||
* Incluye un 'schematic' de generación en tu librería para que con `ng generate` puedas hacer scaffolding de sus artefactos (componentes, servicios, pruebas y etc) en un proyecto.
|
Suppose you want to read a configuration file and then generate a form based on that configuration.
|
||||||
|
If that form will need additional customization by the developer who is using your library, it might work best as a schematic.
|
||||||
|
However, if the forms will always be the same and not need much customization by developers, then you could create a dynamic component that takes the configuration and generates the form.
|
||||||
|
In general, the more complex the customization, the more useful the schematic approach.
|
||||||
|
|
||||||
* Incluye un 'schematic' de actualización para que con `ng update` puedas actualizar las dependencias de tu librería y proporcionar migraciones para cambios importantes en un nuevo release.
|
To learn more, see [Schematics Overview](guide/schematics) and [Schematics for Libraries](guide/schematics-for-libraries).
|
||||||
|
|
||||||
Lo que incluya tu librería depende de tu tarea.
|
## Publishing your library
|
||||||
Por ejemplo, podrías definir un 'schematic' para crear un desplegable (dropdown) que esta pre-poblado con datos para mostrar como agregarlo a una aplicación.
|
|
||||||
Si quieres un desplegable (dropdown) que contendrá valores diferentes cada vez, tu librería podría definir un 'schematic' para crearlo con una configuración dada. Los desarrolladores podrán entonces usar `ng generate` para configurar una instancia para sus propias aplicaciones.
|
|
||||||
|
|
||||||
Supón que quieres leer un archivo de configuración y entonces generar una formulario con base a la configuración.
|
Use the Angular CLI and the npm package manager to build and publish your library as an npm package.
|
||||||
Si este formulario necesita personalización adicional por parte del desarrollador que esta usando tu librería, esto podría trabajar mejor como un 'schematic'.
|
|
||||||
Sin embargo, si el formulario siempre será el mismo y no necesita de mucha personalización por parte de los desarrolladores, entonces podría crear un componente dinámico que tome la configuración y genere el formulario.
|
|
||||||
En general, entre más compleja sea personalización, la más util será en enfoque de un 'schematic'.
|
|
||||||
|
|
||||||
Para aprender más, véase [Vista general de Schematics](guide/schematics) y [Schematics para librerías](guide/schematics-for-libraries).
|
Before publishing a library to NPM, build it using the `--prod` flag which will use the older compiler and runtime known as View Engine instead of Ivy.
|
||||||
|
|
||||||
{@a publishing-your-library}
|
|
||||||
|
|
||||||
## Publicando tu librería
|
|
||||||
|
|
||||||
Usa el Angular CLI y el gestor de paquetes npm para construir y publicar tu librería como un paquete npm.
|
|
||||||
|
|
||||||
Antes de publicar una librería a NPM, constrúyela usando la bandera `--prod` la cúal usará el compilador y tiempo de ejecución (runtime) más antiguos como 'View Engine' en vez de 'Ivy'.
|
|
||||||
|
|
||||||
<code-example language="bash">
|
<code-example language="bash">
|
||||||
ng build my-lib --prod
|
ng build my-lib --prod
|
||||||
@ -128,50 +126,48 @@ cd dist/my-lib
|
|||||||
npm publish
|
npm publish
|
||||||
</code-example>
|
</code-example>
|
||||||
|
|
||||||
Si nunca has publicado un paquete en npm antes, tu debes crear un cuenta. Lee más en [Publicando paquetes npm](https://docs.npmjs.com/getting-started/publishing-npm-packages).
|
If you've never published a package in npm before, you must create a user account. Read more in [Publishing npm Packages](https://docs.npmjs.com/getting-started/publishing-npm-packages).
|
||||||
|
|
||||||
<div class="alert is-important">
|
<div class="alert is-important">
|
||||||
|
|
||||||
Por ahora, no es recomendando publicar librerías con Ivy hacia NPM por que Ivy genera código que no es retrocompatible con 'View Engine', entonces las aplicaciones usando 'View Engine' no podrán consumirlas. Además, las instrucciones internas de IVY no son estables aun, lo cual puede romper potencialmente a los consumidores que usan una diferente versión de Angular a la que uso para construir la libería.
|
For now, it is not recommended to publish Ivy libraries to NPM because Ivy generated code is not backward compatible with View Engine, so apps using View Engine will not be able to consume them. Furthermore, the internal Ivy instructions are not yet stable, which can potentially break consumers using a different Angular version from the one used to build the library.
|
||||||
|
|
||||||
Cuando una librería publicada es usada en una aplicación con Ivy, el Angular CLI automáticamente la convertirá a Ivy usando una herramienta conocida como el compilador de compatibilidad Angular (`ngcc`). Por lo tanto, publicar tus librerías usado el compilador 'View Engine' garantiza que ellas puede ser consumidas de forma transparente por ambos motores 'View Engine' y 'Ivy'.
|
When a published library is used in an Ivy app, the Angular CLI will automatically convert it to Ivy using a tool known as the Angular compatibility compiler (`ngcc`). Thus, publishing your libraries using the View Engine compiler ensures that they can be transparently consumed by both View Engine and Ivy apps.
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{@a lib-assets}
|
{@a lib-assets}
|
||||||
|
|
||||||
## Gestionando activos (assets) en una librería.
|
## Managing assets in a library
|
||||||
|
|
||||||
Desde la versión 9.x de la herramienta [ng-packagr](https://github.com/ng-packagr/ng-packagr/blob/master/README.md), puedes configurar la herramienta para que automáticamente copie los activos (assets) dentro de el paquete de librería como parte del proceso de construcción.
|
Starting with version 9.x of the [ng-packagr](https://github.com/ng-packagr/ng-packagr/blob/master/README.md) tool, you can configure the tool to automatically copy assets into your library package as part of the build process.
|
||||||
Puedes usar esta característica cuando tu librería necesite publicar archivos de temas opcionales, funciones de Sass o documentación (como un registro de cambios 'changelog').
|
You can use this feature when your library needs to publish optional theming files, Sass mixins, or documentation (like a changelog).
|
||||||
|
|
||||||
* Aprende como [copiar activos (assets) dentro de tu librería como parte de la construcción](https://github.com/ng-packagr/ng-packagr/blob/master/docs/copy-assets.md).
|
* Learn how to [copy assets into your library as part of the build](https://github.com/ng-packagr/ng-packagr/blob/master/docs/copy-assets.md).
|
||||||
|
|
||||||
* Aprende más acerca de como usar la herramienta para [incrustar activos (assets) de CSS](https://github.com/ng-packagr/ng-packagr/blob/master/docs/embed-assets-css.md).
|
* Learn more about how to use the tool to [embed assets in CSS](https://github.com/ng-packagr/ng-packagr/blob/master/docs/embed-assets-css.md).
|
||||||
|
|
||||||
|
|
||||||
## Vinculando librerías
|
## Linked libraries
|
||||||
|
|
||||||
Mientras trabajas en un librería publicada, puedes usar [npm link](https://docs.npmjs.com/cli/link) para evitar re instalar la librería en cada construcción.
|
While working on a published library, you can use [npm link](https://docs.npmjs.com/cli/link) to avoid reinstalling the library on every build.
|
||||||
|
|
||||||
La librería debe ser reconstruida en cada cambio.
|
The library must be rebuilt on every change.
|
||||||
Cuando vinculas una librería, asegurate que el paso de construir corra en modo vigía (watch mode) y que el `package.json` de la librería configure los puntos de entrada correctos.
|
When linking a library, make sure that the build step runs in watch mode, and that the library's `package.json` configuration points at the correct entry points.
|
||||||
Por ejemplo, `main` debería apuntar a un archivo JavaScript, no a un archivo TypeScript.
|
For example, `main` should point at a JavaScript file, not a TypeScript file.
|
||||||
|
|
||||||
## Utiliza el mapeo de rutas de TypeScript por las dependencias de pares.
|
## Use TypeScript path mapping for peer dependencies
|
||||||
|
|
||||||
Las librerías de Angular deben enumerar todas las dependencias `@angular/*` como dependencias de pares.
|
Angular libraries should list all `@angular/*` dependencies as peer dependencies.
|
||||||
Esto garantiza que cuando los módulos solicitan Angular, todos ellos obtienen exactamente el mismo módulo.
|
This ensures that when modules ask for Angular, they all get the exact same module.
|
||||||
Si tu librería lista `@angular/core` en `dependencies` en vez de en `peerDependencies`, podría obtener un módulo Angular diferente, lo qué haría que tu aplicación se rompiera.
|
If a library lists `@angular/core` in `dependencies` instead of `peerDependencies`, it might get a different Angular module instead, which would cause your application to break.
|
||||||
|
|
||||||
Cuando desarrollas una librería, tu debes instalar todas las dependencias de pares mediante `devDependencies` para garantizar que la librería compile apropiadamente.
|
While developing a library, you must install all peer dependencies through `devDependencies` to ensure that the library compiles properly.
|
||||||
Una librería vinculada tendrá su propio conjunto de librerías Angular que usa para construir, ubicados en su carpeta `node_modules`.
|
A linked library will then have its own set of Angular libraries that it uses for building, located in its `node_modules` folder.
|
||||||
|
However, this can cause problems while building or running your application.
|
||||||
|
|
||||||
Sin embargo, esto puede causar problemas mientras construyes o corres tu aplicación.
|
To get around this problem you can use TypeScript path mapping to tell TypeScript that it should load some modules from a specific location.
|
||||||
|
List all the peer dependencies that your library uses in the workspace TypeScript configuration file `./tsconfig.json`, and point them at the local copy in the app's `node_modules` folder.
|
||||||
Para evitar este problema tu puedes usar el mapeo de rutas de TypeScript para indicarle a TypeScript que este debería cargar algunos módulos desde una ubicación especifica.
|
|
||||||
|
|
||||||
Enumera todas las dependencias de pares que tu librería usa en el archivo de configuración `./tsconfig.json` del espacio de trabajo de TypeScript, y apúntalos a la copia local en la carpeta `node_modules` de la aplicación.
|
|
||||||
|
|
||||||
```
|
```
|
||||||
{
|
{
|
||||||
@ -187,47 +183,47 @@ Enumera todas las dependencias de pares que tu librería usa en el archivo de co
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
Este mapeador garantiza que tu librería siempre cargue las copias locales del módulo que necesita.
|
This mapping ensures that your library always loads the local copies of the modules it needs.
|
||||||
|
|
||||||
|
|
||||||
## Usando tu propia librería en aplicaciones.
|
## Using your own library in apps
|
||||||
|
|
||||||
No tienes que publicar tu librería hacia el gestor de paquetes npm para usarla en tus propias aplicaciones, pero tienes que construirla primero.
|
You don't have to publish your library to the npm package manager in order to use it in your own apps, but you do have to build it first.
|
||||||
|
|
||||||
Para usar tu propia librería en tu aplicación:
|
To use your own library in an app:
|
||||||
|
|
||||||
* Construye la librería. No puedes usar una librería antes que se construya.
|
* Build the library. You cannot use a library before it is built.
|
||||||
<code-example language="bash">
|
<code-example language="bash">
|
||||||
ng build my-lib
|
ng build my-lib
|
||||||
</code-example>
|
</code-example>
|
||||||
|
|
||||||
* En tus aplicaciones, importa la librería por el nombre:
|
* In your apps, import from the library by name:
|
||||||
```
|
```
|
||||||
import { myExport } from 'my-lib';
|
import { myExport } from 'my-lib';
|
||||||
```
|
```
|
||||||
|
|
||||||
### Construyendo y re construyendo tu librería.
|
### Building and rebuilding your library
|
||||||
|
|
||||||
El paso de construir es importante si no tienes publicada tu librería como un paquete npm y luego ha instalado el paquete de nuevo dentro tu aplicación desde npm.
|
The build step is important if you haven't published your library as an npm package and then installed the package back into your app from npm.
|
||||||
Por ejemplo, si clonas tu repositorio git y corres `npm install`, tu editor mostrará la importación de `my-lib` como perdida si no tienes aun construida tu librería.
|
For instance, if you clone your git repository and run `npm install`, your editor will show the `my-lib` imports as missing if you haven't yet built your library.
|
||||||
|
|
||||||
<div class="alert is-helpful">
|
<div class="alert is-helpful">
|
||||||
|
|
||||||
Cuando importas algo desde una librería en una aplicación Angular, Angular busca un mapeo entre el nombre de librería y una ubicación en disco.
|
When you import something from a library in an Angular app, Angular looks for a mapping between the library name and a location on disk.
|
||||||
Cuando instalas un paquete de librería, el mapeo esta en la carpeta `node_modules`. Cuando construyes tu propia librería, tiene que encontrar el mapeo en tus rutas de `tsconfig`.
|
When you install a library package, the mapping is in the `node_modules` folder. When you build your own library, it has to find the mapping in your `tsconfig` paths.
|
||||||
|
|
||||||
Generando una librería con el Angular CLI automáticamente agrega su ruta en el archivo `tsconfig`.
|
Generating a library with the Angular CLI automatically adds its path to the `tsconfig` file.
|
||||||
El Angular CLI usa las rutas `tsconfig` para indicarle al sistema construido donde encontrar la librería.
|
The Angular CLI uses the `tsconfig` paths to tell the build system where to find the library.
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
Si descubres que los cambios en tu librería no son reflejados en tu aplicación, tu aplicación probablemente esta usando una construcción antigua de la librería.
|
If you find that changes to your library are not reflected in your app, your app is probably using an old build of the library.
|
||||||
|
|
||||||
Puedes re construir tu librería cada vez que hagas cambios en esta, pero este paso extra toma tiempo.
|
You can rebuild your library whenever you make changes to it, but this extra step takes time.
|
||||||
Las *construcciones incrementales* funcionalmente mejoran la experiencia de desarrollo de librerías.
|
*Incremental builds* functionality improves the library-development experience.
|
||||||
Cada vez que un archivo es cambiando una construcción parcial es realizada y esta emite los archivos modificados.
|
Every time a file is changed a partial build is performed that emits the amended files.
|
||||||
|
|
||||||
Las *Construcciones incrementales* puede ser ejecutadas como un proceso en segundo plano en tu entorno de desarrollo. Para aprovechar esta característica agrega la bandera `--watch` al comando de construcción:
|
Incremental builds can be run as a background process in your dev environment. To take advantage of this feature add the `--watch` flag to the build command:
|
||||||
|
|
||||||
<code-example language="bash">
|
<code-example language="bash">
|
||||||
ng build my-lib --watch
|
ng build my-lib --watch
|
||||||
@ -235,15 +231,15 @@ ng build my-lib --watch
|
|||||||
|
|
||||||
<div class="alert is-important">
|
<div class="alert is-important">
|
||||||
|
|
||||||
El comando `build` del CLI utiliza un constructor diferente e invoca una herramienta de construcción diferente para las librerías que para las aplicaciones.
|
The CLI `build` command uses a different builder and invokes a different build tool for libraries than it does for applications.
|
||||||
|
|
||||||
* El sistema de construcción para aplicaciones, `@angular-devkit/build-angular`, esta basado en `webpack`, y esta incluida en todos los nuevos proyectos de Angular CLI.
|
* The build system for apps, `@angular-devkit/build-angular`, is based on `webpack`, and is included in all new Angular CLI projects.
|
||||||
* El sistema de construcción esta basado en `ng-packagr`. Este es solo agregado en tus dependencias cuando agregas una librería usando `ng generate library my-lib`.
|
* The build system for libraries is based on `ng-packagr`. It is only added to your dependencies when you add a library using `ng generate library my-lib`.
|
||||||
|
|
||||||
Los dos sistemas de construcción soportan diferentes cosas e incluso si ellos soportan las mismas cosas, ellos hacen esas cosas de forma diferente.
|
The two build systems support different things, and even where they support the same things, they do those things differently.
|
||||||
Esto quiere decir que la fuente de TypeScript puede generar en código JavaScript diferente en una librería construida que en una aplicación construida.
|
This means that the TypeScript source can result in different JavaScript code in a built library than it would in a built application.
|
||||||
|
|
||||||
Por esta razón, una aplicación que depende de una librería debería solo usar el mapeo de rutas de TypeScript que apunte a la *librería construida*.
|
For this reason, an app that depends on a library should only use TypeScript path mappings that point to the *built library*.
|
||||||
El mapeo de rutas de TypeScript no debería apuntar hacia los archivos `.ts` fuente de la librería.
|
TypeScript path mappings should *not* point to the library source `.ts` files.
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
@ -1,104 +0,0 @@
|
|||||||
# Feature modules
|
|
||||||
|
|
||||||
Feature modules are NgModules for the purpose of organizing code.
|
|
||||||
|
|
||||||
For the final sample app with a feature module that this page describes,
|
|
||||||
see the <live-example></live-example>.
|
|
||||||
|
|
||||||
<hr>
|
|
||||||
|
|
||||||
As your app grows, you can organize code relevant for a specific feature.
|
|
||||||
This helps apply clear boundaries for features. With feature modules,
|
|
||||||
you can keep code related to a specific functionality or feature
|
|
||||||
separate from other code. Delineating areas of your
|
|
||||||
app helps with collaboration between developers and teams, separating
|
|
||||||
directives, and managing the size of the root module.
|
|
||||||
|
|
||||||
## Feature modules vs. root modules
|
|
||||||
|
|
||||||
A feature module is an organizational best practice, as opposed to a concept of the core Angular API. A feature module delivers a cohesive set of functionality focused on a
|
|
||||||
specific application need such as a user workflow, routing, or forms.
|
|
||||||
While you can do everything within the root module, feature modules
|
|
||||||
help you partition the app into focused areas. A feature module
|
|
||||||
collaborates with the root module and with other modules through
|
|
||||||
the services it provides and the components, directives, and
|
|
||||||
pipes that it shares.
|
|
||||||
|
|
||||||
## How to make a feature module
|
|
||||||
|
|
||||||
Assuming you already have an app that you created with the [Angular CLI](cli), create a feature
|
|
||||||
module using the CLI by entering the following command in the
|
|
||||||
root project directory. Replace `CustomerDashboard` with the
|
|
||||||
name of your module. You can omit the "Module" suffix from the name because the CLI appends it:
|
|
||||||
|
|
||||||
```sh
|
|
||||||
ng generate module CustomerDashboard
|
|
||||||
|
|
||||||
```
|
|
||||||
|
|
||||||
This causes the CLI to create a folder called `customer-dashboard` with a file inside called `customer-dashboard.module.ts` with the following contents:
|
|
||||||
|
|
||||||
```typescript
|
|
||||||
import { NgModule } from "@angular/core";
|
|
||||||
import { CommonModule } from "@angular/common";
|
|
||||||
|
|
||||||
@NgModule({
|
|
||||||
imports: [CommonModule],
|
|
||||||
declarations: [],
|
|
||||||
})
|
|
||||||
export class CustomerDashboardModule {}
|
|
||||||
```
|
|
||||||
|
|
||||||
The structure of an NgModule is the same whether it is a root module or a feature module. In the CLI generated feature module, there are two JavaScript import statements at the top of the file: the first imports `NgModule`, which, like the root module, lets you use the `@NgModule` decorator; the second imports `CommonModule`, which contributes many common directives such as `ngIf` and `ngFor`. Feature modules import `CommonModule` instead of `BrowserModule`, which is only imported once in the root module. `CommonModule` only contains information for common directives such as `ngIf` and `ngFor` which are needed in most templates, whereas `BrowserModule` configures the Angular app for the browser which needs to be done only once.
|
|
||||||
|
|
||||||
The `declarations` array is available for you to add declarables, which
|
|
||||||
are components, directives, and pipes that belong exclusively to this particular module. To add a component, enter the following command at the command line where `customer-dashboard` is the directory where the CLI generated the feature module and `CustomerDashboard` is the name of the component:
|
|
||||||
|
|
||||||
```sh
|
|
||||||
ng generate component customer-dashboard/CustomerDashboard
|
|
||||||
|
|
||||||
```
|
|
||||||
|
|
||||||
This generates a folder for the new component within the customer-dashboard folder and updates the feature module with the `CustomerDashboardComponent` info:
|
|
||||||
|
|
||||||
<code-example path="feature-modules/src/app/customer-dashboard/customer-dashboard.module.ts" region="customer-dashboard-component" header="src/app/customer-dashboard/customer-dashboard.module.ts"></code-example>
|
|
||||||
|
|
||||||
The `CustomerDashboardComponent` is now in the JavaScript import list at the top and added to the `declarations` array, which lets Angular know to associate this new component with this feature module.
|
|
||||||
|
|
||||||
## Importing a feature module
|
|
||||||
|
|
||||||
To incorporate the feature module into your app, you have to let the root module, `app.module.ts`, know about it. Notice the `CustomerDashboardModule` export at the bottom of `customer-dashboard.module.ts`. This exposes it so that other modules can get to it. To import it into the `AppModule`, add it to the imports in `app.module.ts` and to the `imports` array:
|
|
||||||
|
|
||||||
<code-example path="feature-modules/src/app/app.module.ts" region="app-module" header="src/app/app.module.ts"></code-example>
|
|
||||||
|
|
||||||
Now the `AppModule` knows about the feature module. If you were to add any service providers to the feature module, `AppModule` would know about those too, as would any other feature modules. However, NgModules don’t expose their components.
|
|
||||||
|
|
||||||
## Rendering a feature module’s component template
|
|
||||||
|
|
||||||
When the CLI generated the `CustomerDashboardComponent` for the feature module, it included a template, `customer-dashboard.component.html`, with the following markup:
|
|
||||||
|
|
||||||
<code-example path="feature-modules/src/app/customer-dashboard/customer-dashboard/customer-dashboard.component.html" region="feature-template" header="src/app/customer-dashboard/customer-dashboard/customer-dashboard.component.html"></code-example>
|
|
||||||
|
|
||||||
To see this HTML in the `AppComponent`, you first have to export the `CustomerDashboardComponent` in the `CustomerDashboardModule`. In `customer-dashboard.module.ts`, just beneath the `declarations` array, add an `exports` array containing `CustomerDashboardComponent`:
|
|
||||||
|
|
||||||
<code-example path="feature-modules/src/app/customer-dashboard/customer-dashboard.module.ts" region="component-exports" header="src/app/customer-dashboard/customer-dashboard.module.ts"></code-example>
|
|
||||||
|
|
||||||
Next, in the `AppComponent`, `app.component.html`, add the tag `<app-customer-dashboard>`:
|
|
||||||
|
|
||||||
<code-example path="feature-modules/src/app/app.component.html" region="app-component-template" header="src/app/app.component.html"></code-example>
|
|
||||||
|
|
||||||
Now, in addition to the title that renders by default, the `CustomerDashboardComponent` template renders too:
|
|
||||||
|
|
||||||
<div class="lightbox">
|
|
||||||
<img src="generated/images/guide/feature-modules/feature-module.png" alt="feature module component">
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<hr />
|
|
||||||
|
|
||||||
## More on NgModules
|
|
||||||
|
|
||||||
You may also be interested in the following:
|
|
||||||
|
|
||||||
- [Lazy Loading Modules with the Angular Router](guide/lazy-loading-ngmodules).
|
|
||||||
- [Providers](guide/providers).
|
|
||||||
- [Types of Feature Modules](guide/module-types).
|
|
@ -1,79 +1,106 @@
|
|||||||
# Módulos de funcionalidades
|
# Feature modules
|
||||||
|
|
||||||
Los módulos de funcionalidades son NgModules con el propósito de organizar el código.
|
Feature modules are NgModules for the purpose of organizing code.
|
||||||
|
|
||||||
Para la aplicación de muestra final con un módulo de funcionalidades que se describe en esta página,
|
For the final sample app with a feature module that this page describes,
|
||||||
ver el <live-example> </live-example>.
|
see the <live-example></live-example>.
|
||||||
|
|
||||||
<hr>
|
<hr>
|
||||||
|
|
||||||
A medida que tu aplicación crece, puedes organizar el código relevante para una funcionalidad específica. Esto ayuda a aplicar límites claros para las funcionalidades. Con módulos de funcionalidades,
|
As your app grows, you can organize code relevant for a specific feature.
|
||||||
puedes mantener el código relacionado con una funcionalidad o característica específica
|
This helps apply clear boundaries for features. With feature modules,
|
||||||
separado de otro código. Delinear áreas de suaplicación ayuda con la colaboración entre desarrolladores y equipos, separando directivas y gestionar el tamaño del módulo raíz.
|
you can keep code related to a specific functionality or feature
|
||||||
|
separate from other code. Delineating areas of your
|
||||||
|
app helps with collaboration between developers and teams, separating
|
||||||
|
directives, and managing the size of the root module.
|
||||||
|
|
||||||
## Módulos de funcionalidades frente a módulos raíz
|
|
||||||
|
|
||||||
Un módulo de funcionalidades es una mejor práctica organizativa, a diferencia de un concepto de la API angular principal. Un módulo de funcionalidades ofrece un conjunto coherente de funcionalidades centradas en una necesidad de aplicación específica, como un flujo de trabajo, enrutamiento o formularios de usuario. Si bien puede hacer todo dentro del módulo raíz, los módulos de funcionalidades lo ayudan a dividir la aplicación en áreas específicas. Un módulo de funcionalidades colabora con el módulo raíz y con otros módulos a través de los servicios que proporciona y los componentes, directivas y canalizaciones que comparte.
|
## Feature modules vs. root modules
|
||||||
|
|
||||||
## Cómo hacer un módulo de funcionalidades
|
A feature module is an organizational best practice, as opposed to a concept of the core Angular API. A feature module delivers a cohesive set of functionality focused on a
|
||||||
|
specific application need such as a user workflow, routing, or forms.
|
||||||
|
While you can do everything within the root module, feature modules
|
||||||
|
help you partition the app into focused areas. A feature module
|
||||||
|
collaborates with the root module and with other modules through
|
||||||
|
the services it provides and the components, directives, and
|
||||||
|
pipes that it shares.
|
||||||
|
|
||||||
Suponiendo que ya tienes una aplicación que creó con la [CLI Angular](cli), crea un módulo de funcionalidades usando la CLI ingresando el siguiente comando en el directorio raíz del proyecto. Reemplaza `CustomerDashboard` con el nombre de tu módulo. Puedes omitir el sufijo "Módulo" / "Module" del nombre porque la CLI lo agrega:
|
## How to make a feature module
|
||||||
|
|
||||||
|
Assuming you already have an app that you created with the [Angular CLI](cli), create a feature
|
||||||
|
module using the CLI by entering the following command in the
|
||||||
|
root project directory. Replace `CustomerDashboard` with the
|
||||||
|
name of your module. You can omit the "Module" suffix from the name because the CLI appends it:
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
ng generate module CustomerDashboard
|
ng generate module CustomerDashboard
|
||||||
|
|
||||||
```
|
```
|
||||||
|
|
||||||
Esto hace que la CLI cree una carpeta llamada `customer-dashboard` con un archivo dentro llamado` customer-dashboard.module.ts` con el siguiente contenido:
|
|
||||||
|
This causes the CLI to create a folder called `customer-dashboard` with a file inside called `customer-dashboard.module.ts` with the following contents:
|
||||||
|
|
||||||
```typescript
|
```typescript
|
||||||
import { NgModule } from '@angular/core';
|
import { NgModule } from '@angular/core';
|
||||||
import { CommonModule } from '@angular/common';
|
import { CommonModule } from '@angular/common';
|
||||||
|
|
||||||
@NgModule({
|
@NgModule({
|
||||||
imports: [CommonModule],
|
imports: [
|
||||||
declarations: [],
|
CommonModule
|
||||||
|
],
|
||||||
|
declarations: []
|
||||||
})
|
})
|
||||||
export class CustomerDashboardModule {}
|
export class CustomerDashboardModule { }
|
||||||
```
|
```
|
||||||
|
|
||||||
La estructura de un NgModule es la misma si es un módulo raíz o un módulo de funcionalidades. En el módulo de funcionalidades generado por CLI, hay dos declaraciones de importación de JavaScript en la parte superior del archivo: la primera importa `NgModule`, que, como el módulo raíz, le permite usar el decorador `@NgModule`; el segundo importa `CommonModule`, que aporta muchas directivas comunes como `ngIf` y `ngFor`. Los módulos de funcionalidades importan `CommonModule` en lugar de `BrowserModule`, que solo se importa una vez en el módulo raíz. `CommonModule` solo contiene información para directivas comunes como `ngIf` y `ngFor` que se necesitan en la mayoría de las plantillas, mientras que `BrowserModule` configura la aplicación Angular para el navegador, lo cual debe hacerse solo una vez.
|
The structure of an NgModule is the same whether it is a root module or a feature module. In the CLI generated feature module, there are two JavaScript import statements at the top of the file: the first imports `NgModule`, which, like the root module, lets you use the `@NgModule` decorator; the second imports `CommonModule`, which contributes many common directives such as `ngIf` and `ngFor`. Feature modules import `CommonModule` instead of `BrowserModule`, which is only imported once in the root module. `CommonModule` only contains information for common directives such as `ngIf` and `ngFor` which are needed in most templates, whereas `BrowserModule` configures the Angular app for the browser which needs to be done only once.
|
||||||
|
|
||||||
La matriz `declaraciones` está disponible para que agregue declarables, que son componentes, directivas y canalizaciones que pertenecen exclusivamente a este módulo en particular. Para agregar un componente, ingresa el siguiente comando en la línea de comando donde `customer-dashboard` es el directorio donde la CLI generó el módulo de funciones y CustomerDashboard` es el nombre del componente:
|
The `declarations` array is available for you to add declarables, which
|
||||||
|
are components, directives, and pipes that belong exclusively to this particular module. To add a component, enter the following command at the command line where `customer-dashboard` is the directory where the CLI generated the feature module and `CustomerDashboard` is the name of the component:
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
ng generate component customer-dashboard/CustomerDashboard
|
ng generate component customer-dashboard/CustomerDashboard
|
||||||
|
|
||||||
```
|
```
|
||||||
|
|
||||||
Esto genera una carpeta para el nuevo componente dentro de la carpeta del panel del cliente y actualiza el módulo de funcionalidades con la información de `CustomerDashboardComponent`:
|
This generates a folder for the new component within the customer-dashboard folder and updates the feature module with the `CustomerDashboardComponent` info:
|
||||||
|
|
||||||
|
|
||||||
<code-example path="feature-modules/src/app/customer-dashboard/customer-dashboard.module.ts" region="customer-dashboard-component" header="src/app/customer-dashboard/customer-dashboard.module.ts"></code-example>
|
<code-example path="feature-modules/src/app/customer-dashboard/customer-dashboard.module.ts" region="customer-dashboard-component" header="src/app/customer-dashboard/customer-dashboard.module.ts"></code-example>
|
||||||
|
|
||||||
El `CustomerDashboardComponent` ahora se encuentra en la lista de importación de JavaScript en la parte superior y se agregó a la matriz de `declaraciones`, lo que le permite a Angular asociar este nuevo componente con este módulo de funciones.
|
|
||||||
|
|
||||||
## Importación de un módulo de funcionalidades
|
|
||||||
|
|
||||||
Para incorporar el módulo de funcionalidades en tu aplicación, debes informar al módulo raíz, `app.module.ts`. Observa la exportación de "CustomerDashboardModule" en la parte inferior de `customer-dashboard.module.ts`. Esto lo expone para que otros módulos puedan acceder a él. Para importarlo en el `AppModule`, agrégalo a las importaciones en` app.module.ts` y al arreglo de `import`:
|
The `CustomerDashboardComponent` is now in the JavaScript import list at the top and added to the `declarations` array, which lets Angular know to associate this new component with this feature module.
|
||||||
|
|
||||||
|
## Importing a feature module
|
||||||
|
|
||||||
|
To incorporate the feature module into your app, you have to let the root module, `app.module.ts`, know about it. Notice the `CustomerDashboardModule` export at the bottom of `customer-dashboard.module.ts`. This exposes it so that other modules can get to it. To import it into the `AppModule`, add it to the imports in `app.module.ts` and to the `imports` array:
|
||||||
|
|
||||||
<code-example path="feature-modules/src/app/app.module.ts" region="app-module" header="src/app/app.module.ts"></code-example>
|
<code-example path="feature-modules/src/app/app.module.ts" region="app-module" header="src/app/app.module.ts"></code-example>
|
||||||
|
|
||||||
Ahora el `AppModule` conoce el módulo de funcionalidades. Si tuviera que agregar cualquier proveedor de servicios al módulo de funcionalidades, `AppModule` también lo conocería, al igual que cualquier otro módulo de funcionalidades. Sin embargo, los NgModules no exponen sus componentes.
|
|
||||||
|
|
||||||
## Representación de la plantilla de componente de un módulo de funcionalidades
|
Now the `AppModule` knows about the feature module. If you were to add any service providers to the feature module, `AppModule` would know about those too, as would any other feature modules. However, NgModules don’t expose their components.
|
||||||
|
|
||||||
Cuando la CLI generó el `CustomerDashboardComponent` para el módulo de funcionalidades, incluyó una plantilla, `customer-dashboard.component.html`, con el siguiente marcado:
|
|
||||||
|
## Rendering a feature module’s component template
|
||||||
|
|
||||||
|
When the CLI generated the `CustomerDashboardComponent` for the feature module, it included a template, `customer-dashboard.component.html`, with the following markup:
|
||||||
|
|
||||||
<code-example path="feature-modules/src/app/customer-dashboard/customer-dashboard/customer-dashboard.component.html" region="feature-template" header="src/app/customer-dashboard/customer-dashboard/customer-dashboard.component.html"></code-example>
|
<code-example path="feature-modules/src/app/customer-dashboard/customer-dashboard/customer-dashboard.component.html" region="feature-template" header="src/app/customer-dashboard/customer-dashboard/customer-dashboard.component.html"></code-example>
|
||||||
|
|
||||||
Para ver este HTML en el `AppComponent`, primero tienes que exportar el `CustomerDashboardComponent` en el `CustomerDashboardModule`. En `customer-dashboard.module.ts`, justo debajo de la matriz de `declaraciones`, agrega una matriz de `exportaciones` que contenga `CustomerDashboardComponent`:
|
|
||||||
|
To see this HTML in the `AppComponent`, you first have to export the `CustomerDashboardComponent` in the `CustomerDashboardModule`. In `customer-dashboard.module.ts`, just beneath the `declarations` array, add an `exports` array containing `CustomerDashboardComponent`:
|
||||||
|
|
||||||
<code-example path="feature-modules/src/app/customer-dashboard/customer-dashboard.module.ts" region="component-exports" header="src/app/customer-dashboard/customer-dashboard.module.ts"></code-example>
|
<code-example path="feature-modules/src/app/customer-dashboard/customer-dashboard.module.ts" region="component-exports" header="src/app/customer-dashboard/customer-dashboard.module.ts"></code-example>
|
||||||
|
|
||||||
Luego, en el `AppComponent`, `app.component.html`, agrega la etiqueta `<app-customer-dashboard>`:
|
|
||||||
|
|
||||||
|
Next, in the `AppComponent`, `app.component.html`, add the tag `<app-customer-dashboard>`:
|
||||||
|
|
||||||
<code-example path="feature-modules/src/app/app.component.html" region="app-component-template" header="src/app/app.component.html"></code-example>
|
<code-example path="feature-modules/src/app/app.component.html" region="app-component-template" header="src/app/app.component.html"></code-example>
|
||||||
|
|
||||||
Ahora, además del título que se representa de forma predeterminada, la plantilla `CustomerDashboardComponent` también se representa:
|
|
||||||
|
Now, in addition to the title that renders by default, the `CustomerDashboardComponent` template renders too:
|
||||||
|
|
||||||
<div class="lightbox">
|
<div class="lightbox">
|
||||||
<img src="generated/images/guide/feature-modules/feature-module.png" alt="feature module component">
|
<img src="generated/images/guide/feature-modules/feature-module.png" alt="feature module component">
|
||||||
@ -81,10 +108,9 @@ Ahora, además del título que se representa de forma predeterminada, la plantil
|
|||||||
|
|
||||||
<hr />
|
<hr />
|
||||||
|
|
||||||
## Más sobre NgModules
|
## More on NgModules
|
||||||
|
|
||||||
También te puede interesar lo siguiente:
|
You may also be interested in the following:
|
||||||
|
* [Lazy Loading Modules with the Angular Router](guide/lazy-loading-ngmodules).
|
||||||
- [Módulos de carga diferida con el enrutador angular](guide/lazy-loading-ngmodules).
|
* [Providers](guide/providers).
|
||||||
- [Proveedores](guide/providers).
|
* [Types of Feature Modules](guide/module-types).
|
||||||
- [Tipos de módulos de funciones](guide/module-types).
|
|
||||||
|
@ -22,7 +22,7 @@ Una estructura que proporciona metadatos para una clase. Ver [decorador](#decora
|
|||||||
|
|
||||||
Es una herramienta que utiliza la CLI para realizar tareas complejas, como la compilación y la ejecución de pruebas, de acuerdo con una configuración proporcionada.
|
Es una herramienta que utiliza la CLI para realizar tareas complejas, como la compilación y la ejecución de pruebas, de acuerdo con una configuración proporcionada.
|
||||||
|
|
||||||
El architect es un shell que ejecuta un [constructor](#builder) (definido en un [paquete npm](#npm-package)) con una [configuración de destino](#target) dada.
|
El architect es un shell que ejecuta un [constructor](#builder) (definido en un [paquete npm](#npm-package)) con una [configuración de destino] dada (#target).
|
||||||
|
|
||||||
En el [archivo de configuración del espacio de trabajo](guide/workspace-config#project-tool-configuration-options), una sección de "architect" proporciona opciones de configuración para los architects constructores.
|
En el [archivo de configuración del espacio de trabajo](guide/workspace-config#project-tool-configuration-options), una sección de "architect" proporciona opciones de configuración para los architects constructores.
|
||||||
|
|
||||||
@ -105,15 +105,15 @@ La compilación ahead-of-time (AOT) de Angular convierte el código Angular HTML
|
|||||||
|
|
||||||
Este es el mejor modo de compilación para entornos de producción, con un menor tiempo de carga y un mayor rendimiento en comparación con [compilación just-in-time (JIT)](#jit).
|
Este es el mejor modo de compilación para entornos de producción, con un menor tiempo de carga y un mayor rendimiento en comparación con [compilación just-in-time (JIT)](#jit).
|
||||||
|
|
||||||
Al compilar tu aplicación utilizando la herramienta de línea de comandos `ngc`, puedes iniciar directamente a una module factory, por lo que no necesitas incluir el compilador Angular en tu paquete de JavaScript.
|
Al compilar su aplicación utilizando la herramienta de línea de comandos `ngc`, puede iniciar directamente a una module factory, por lo que no necesita incluir el compilador Angular en su paquete de JavaScript.
|
||||||
|
|
||||||
{@a jit}
|
{@a jit}
|
||||||
|
|
||||||
## compilación just-in-time (JIT)
|
## compilación just-in-time (JIT)
|
||||||
|
|
||||||
El compilador Angular just-in-time (JIT) convierte tu código Angular HTML y TypeScript en código JavaScript eficiente en tiempo de ejecución, como parte del arranque.
|
El compilador Angular just-in-time (JIT) convierte su código Angular HTML y TypeScript en código JavaScript eficiente en tiempo de ejecución, como parte del arranque.
|
||||||
|
|
||||||
La compilación JIT es el valor predeterminado (a diferencia de la compilación AOT) cuando ejecutas los comandos CLI `ng build` y`ng serve` de Angular, y es una buena opción durante el desarrollo.
|
La compilación JIT es el valor predeterminado (a diferencia de la compilación AOT) cuando ejecuta los comandos CLI `ng build` y`ng serve` de Angular, y es una buena opción durante el desarrollo.
|
||||||
El modo JIT no se recomienda para el uso en producción porque da como resultado grandes cargas útiles de aplicaciones que dificultan el rendimiento de arranque.
|
El modo JIT no se recomienda para el uso en producción porque da como resultado grandes cargas útiles de aplicaciones que dificultan el rendimiento de arranque.
|
||||||
|
|
||||||
Comparar con [compilación ahead-of-time (AOT)](#aot).
|
Comparar con [compilación ahead-of-time (AOT)](#aot).
|
||||||
@ -188,10 +188,10 @@ El detector de cambios es responsable de actualizar la vista para reflejar el mo
|
|||||||
Del mismo modo, el usuario puede interactuar con la interfaz de usuario, lo que provoca eventos que cambian el estado del modelo de datos.
|
Del mismo modo, el usuario puede interactuar con la interfaz de usuario, lo que provoca eventos que cambian el estado del modelo de datos.
|
||||||
Estos eventos pueden desencadenar la detección de cambios.
|
Estos eventos pueden desencadenar la detección de cambios.
|
||||||
|
|
||||||
Usando la estrategia de detección de cambio predeterminada ("CheckAlways"), el detector de cambio pasa por la [jerarquía de vista](#view-tree) en cada turno de VM para verificar cada [propiedad vinculada a datos](#data-binding) en la plantilla. En la primera fase, compara el estado actual de los datos dependientes con el estado anterior y recopila los cambios.
|
Usando la estrategia de detección de cambio predeterminada ("CheckAlways"), el detector de cambio pasa por la [jerarquía de vista](#view-tree) en cada turno de VM para verificar cada [propiedad vinculada a datos](#data-binding) en la plantilla. en el modelo. En la primera fase, compara el estado actual de los datos dependientes con el estado anterior y recopila los cambios.
|
||||||
En la segunda fase, actualiza la página DOM para reflejar los nuevos valores de datos.
|
En la segunda fase, actualiza la página DOM para reflejar los nuevos valores de datos.
|
||||||
|
|
||||||
Si configuras la estrategia de detección de cambios `OnPush` ("CheckOnce"), el detector de cambios se ejecuta solo cuando es [invocado explícitamente](api/core/ChangeDetectorRef), o cuando se activa mediante un cambio de referencia en mediante un `Input` o un controlador de eventos. Esto generalmente mejora el rendimiento. Para obtener más información, consulta [Optimizar la detección de cambios de Angular](https://web.dev/faster-angular-change-detection/).
|
Si configuras la estrategia de detección de cambios `OnPush` ("CheckOnce"), el detector de cambios se ejecuta solo cuando [invocado explícitamente](api/core/ChangeDetectorRef), o cuando se activa mediante un cambio de referencia en mediante un `Input` o un controlador de eventos. Esto generalmente mejora el rendimiento. Para obtener más información, consulta [Optimizar la detección de cambios de Angular](https://web.dev/faster-angular-change-detection/).
|
||||||
|
|
||||||
{@a class-decorator}
|
{@a class-decorator}
|
||||||
|
|
||||||
@ -227,7 +227,7 @@ Obtén más información en [Directivas de atributos](guide/attribute-directives
|
|||||||
|
|
||||||
## directivas estructurales
|
## directivas estructurales
|
||||||
|
|
||||||
Una categoría de [directiva](#directive) que es responsable de dar forma al diseño HTML modificando el DOM, es decir, agregando, eliminando o manipulando elementos y sus elementos secundarios.
|
Una categoría de [directiva](#directive) que es responsable de dar forma al diseño HTML modificando DOM y mdashthat, es decir, agregando, eliminando o manipulando elementos y sus elementos secundarios.
|
||||||
|
|
||||||
Obtén más información en [Directivas estructurales](guide/structural-directives).
|
Obtén más información en [Directivas estructurales](guide/structural-directives).
|
||||||
|
|
||||||
@ -263,7 +263,7 @@ Consulta [decorador de clase](#class-decorator), [decorador de campo de clase](#
|
|||||||
|
|
||||||
## directiva
|
## directiva
|
||||||
|
|
||||||
Una clase que puede modificar la estructura del DOM o modificar atributos en el DOM y el modelo de datos de componentes. Una definición de clase directiva está precedida inmediatamente por un [decorador](#decorator) `@Directive()` que proporciona metadatos.
|
Una clase que puede modificar la estructura del DOM o modificar atributos en el DOM y el modelo de datos de componentes. Una definición de clase directiva está precedida inmediatamente por un `@Directive()` [decorador](#decorator) que proporciona metadatos.
|
||||||
|
|
||||||
Una clase de directiva generalmente está asociada con un elemento o atributo HTML, y ese elemento o atributo a menudo se conoce como la directiva misma. Cuando Angular encuentra una directiva en una [plantilla](#template) HTML, crea la instancia de clase de directiva coincidente y le da a la instancia control sobre esa parte del DOM del navegador.
|
Una clase de directiva generalmente está asociada con un elemento o atributo HTML, y ese elemento o atributo a menudo se conoce como la directiva misma. Cuando Angular encuentra una directiva en una [plantilla](#template) HTML, crea la instancia de clase de directiva coincidente y le da a la instancia control sobre esa parte del DOM del navegador.
|
||||||
|
|
||||||
@ -276,8 +276,8 @@ Hay tres categorías de directivas:
|
|||||||
- [Directivas estructurales](#structural-directive) modifican la estructura del DOM.
|
- [Directivas estructurales](#structural-directive) modifican la estructura del DOM.
|
||||||
|
|
||||||
Angular proporciona una serie de directivas integradas que comienzan con el prefijo `ng`.
|
Angular proporciona una serie de directivas integradas que comienzan con el prefijo `ng`.
|
||||||
También puedes crear nuevas directivas para implementar tu propia funcionalidad.
|
También puede crear nuevas directivas para implementar su propia funcionalidad.
|
||||||
Asocia un _selector_ (una etiqueta HTML como `<my-directive>`) con una directiva personalizada, extendiendo así la [sintaxis de plantilla](guide/template-syntax) que puede usar en tus aplicaciones.
|
Asocia un _selector_ (una etiqueta HTML como `<my-directive>`) con una directiva personalizada, extendiendo así la [sintaxis de plantilla](guide/template-syntax) que puede usar en sus aplicaciones.
|
||||||
|
|
||||||
{@a E}
|
{@a E}
|
||||||
|
|
||||||
@ -287,15 +287,15 @@ Asocia un _selector_ (una etiqueta HTML como `<my-directive>`) con una directiva
|
|||||||
|
|
||||||
La [especificación oficial del lenguaje JavaScript](https://es.wikipedia.org/wiki/ECMAScript).
|
La [especificación oficial del lenguaje JavaScript](https://es.wikipedia.org/wiki/ECMAScript).
|
||||||
|
|
||||||
No todos los navegadores son compatibles con el último estándar ECMAScript, pero puedes usar un [transpiler](#transpile) (como [TypeScript](#typescript)) para escribir código utilizando las últimas funciones, que luego se transpilarán al código que se ejecuta en las versiones que son compatibles con los navegadores.
|
No todos los navegadores son compatibles con el último estándar ECMAScript, pero puede usar un [transpiler](#transpile) (como [TypeScript](#typescript)) para escribir código utilizando las últimas funciones, que luego se transpilarán al código que se ejecuta en las versiones que son compatibles con los navegadores.
|
||||||
|
|
||||||
Para obtener más información, consulta [Browser Support](guide/browser-support).
|
Para obtener más información, consultá [Browser Support](guide/browser-support).
|
||||||
|
|
||||||
{@a binding}
|
{@a binding}
|
||||||
|
|
||||||
## enlaces (binding)
|
## enlaces (binding)
|
||||||
|
|
||||||
En general, es la práctica de establecer una variable o propiedad en un valor de datos. Dentro de Angular, generalmente se refiere a [enlace de datos](#data-binding), que coordina las propiedades del objeto DOM con las propiedades del objeto de datos.
|
En general, es la práctica de establecer una variable o propiedad en un valor de datos Dentro de Angular, generalmente se refiere a [enlace de datos](#data-binding), que coordina las propiedades del objeto DOM con las propiedades del objeto de datos.
|
||||||
|
|
||||||
A veces se refiere a una [inyección de dependencia](#dependency-injection) de enlace
|
A veces se refiere a una [inyección de dependencia](#dependency-injection) de enlace
|
||||||
entre un [token](#token) y una dependencia de [proveedor](#provider).
|
entre un [token](#token) y una dependencia de [proveedor](#provider).
|
||||||
@ -340,7 +340,7 @@ Una herramienta que configura e implementa la navegación entre estados y [vista
|
|||||||
|
|
||||||
El módulo `Router` es un [NgModule](#ngmodule) que proporciona los proveedores de servicios y las directivas necesarias para navegar por las vistas de la aplicación. Un [componente de enrutamiento](#router-outlet) es aquel que importa el módulo `Router` y cuya plantilla contiene un elemento `RouterOutlet` donde puede mostrar vistas producidas por el enrutador.
|
El módulo `Router` es un [NgModule](#ngmodule) que proporciona los proveedores de servicios y las directivas necesarias para navegar por las vistas de la aplicación. Un [componente de enrutamiento](#router-outlet) es aquel que importa el módulo `Router` y cuya plantilla contiene un elemento `RouterOutlet` donde puede mostrar vistas producidas por el enrutador.
|
||||||
|
|
||||||
A diferencia de la navegación entre páginas, el enrutador define la navegación entre vistas en una sola página. Interpreta enlaces de tipo URL para determinar qué vistas crear o destruir, y qué componentes cargar o descargar. Te permite aprovechar la [carga diferida](#lazy-load) en las aplicaciones Angular.
|
El enrutador define la navegación entre vistas en una sola página, a diferencia de la navegación entre páginas. Interpreta enlaces de tipo URL para determinar qué vistas crear o destruir, y qué componentes cargar o descargar. Le permite aprovechar [carga diferida](#lazy-load) en las aplicaciones Angular.
|
||||||
|
|
||||||
Obtén más información en [Enrutamiento y navegación](guide/router).
|
Obtén más información en [Enrutamiento y navegación](guide/router).
|
||||||
|
|
||||||
@ -353,7 +353,7 @@ En la mayoría de los casos, esto le permite usar plantillas de Angular y enlace
|
|||||||
|
|
||||||
La documentación generalmente se refiere a _elementos_ (instancias `ElementRef`), a diferencia de _elementos DOM_ (que se puede acceder directamente si es necesario).
|
La documentación generalmente se refiere a _elementos_ (instancias `ElementRef`), a diferencia de _elementos DOM_ (que se puede acceder directamente si es necesario).
|
||||||
|
|
||||||
Comparar con [elemento personalizado](#custom-element).
|
Comparado con [elemento personalizado](#custom-element).
|
||||||
|
|
||||||
{@a angular-element}
|
{@a angular-element}
|
||||||
|
|
||||||
@ -404,15 +404,15 @@ Usando Node 6.9 o superior, instala la CLI de esquemas globalmente:
|
|||||||
npm install -g @angular-devkit/schematics-cli
|
npm install -g @angular-devkit/schematics-cli
|
||||||
</code-example>
|
</code-example>
|
||||||
|
|
||||||
Esto instala el ejecutable `schematics`, que puedes usar para crear un nuevo esquema [colección](#collection) con un esquema inicial llamado. La carpeta de colección es un espacio de trabajo para esquemas. También puedes usar el comando `schematics` para agregar un nuevo esquema a una colección existente, o extender un esquema existente.
|
Esto instala el ejecutable `schematics`, que puede usar para crear un nuevo esquema [colección](#collection) con un esquema inicial llamado. La carpeta de colección es un espacio de trabajo para esquemas. También puede usar el comando `schematics` para agregar un nuevo esquema a una colección existente, o extender un esquema existente.
|
||||||
|
|
||||||
{@a workspace}
|
{@a workspace}
|
||||||
|
|
||||||
## espacio de trabajo
|
## espacio de trabajo
|
||||||
|
|
||||||
Una colección de [proyectos](#project) Angular (es decir, aplicaciones y librerías) con tecnología de [Angular CLI](#cli) que generalmente se ubican en un único repositorio de control de fuente (como [git](https://git-scm.com/)).
|
Una colección de [proyectos](#project) Angular (es decir, aplicaciones y librerías) con tecnología de [anglar CLI](#cli) que generalmente se ubican en un único repositorio de control de fuente (como [git](https://git-scm.com/)).
|
||||||
|
|
||||||
El [comando CLI `ng new`](cli/new) crea un directorio del sistema de archivos (la "raíz del espacio de trabajo"). En la raíz del espacio de trabajo, también crea el espacio de trabajo [archivo de configuración](#configuration) (`angular.json`) y, por defecto, un proyecto de aplicación inicial con el mismo nombre.
|
El [CLI](#cli) [`ng new` command](cli/new) crea un directorio del sistema de archivos (la "raíz del espacio de trabajo"). En la raíz del espacio de trabajo, también crea el espacio de trabajo [archivo de configuración](#configuration) (`angular.json`) y, por defecto, un proyecto de aplicación inicial con el mismo nombre.
|
||||||
|
|
||||||
Los comandos que crean u operan en aplicaciones y librerías (como `add` y `generate`) deben ejecutarse desde una carpeta de espacio de trabajo.
|
Los comandos que crean u operan en aplicaciones y librerías (como `add` y `generate`) deben ejecutarse desde una carpeta de espacio de trabajo.
|
||||||
|
|
||||||
@ -457,9 +457,9 @@ Cuando se usan formularios reactivos:
|
|||||||
- La validación se configura mediante funciones de validación en lugar de directivas de validación.
|
- La validación se configura mediante funciones de validación en lugar de directivas de validación.
|
||||||
- Cada control se crea explícitamente en la clase de componente creando una instancia de `FormControl` manualmente o con `FormBuilder`.
|
- Cada control se crea explícitamente en la clase de componente creando una instancia de `FormControl` manualmente o con `FormBuilder`.
|
||||||
- Los elementos de entrada de la plantilla _no_ usan `ngModel`.
|
- Los elementos de entrada de la plantilla _no_ usan `ngModel`.
|
||||||
- Las directivas Angular asociadas tienen el prefijo `form`, como `formControl`, `formGroup` y `formControlName`.
|
- as directivas Angular asociadas tienen el prefijo `form`, como `formControl`, `formGroup` y `formControlName`.
|
||||||
|
|
||||||
La alternativa es un formulario basado en plantillas. Para una introducción y comparación de ambos enfoques de formularios, consulta [Introducción a los formularios Angular](guide/forms-overview).
|
La alternativa es un formulario basado en plantillas. Para una introducción y comparación de ambos enfoques de formularios, consulte [Introducción a los formularios Angular](guide/forms-overview).
|
||||||
|
|
||||||
{@a unidirectional-data-flow}
|
{@a unidirectional-data-flow}
|
||||||
|
|
||||||
@ -470,9 +470,9 @@ Un modelo de flujo de datos donde el árbol de componentes siempre se verifica e
|
|||||||
En la práctica, esto significa que los datos en Angular fluyen hacia abajo durante la detección de cambios.
|
En la práctica, esto significa que los datos en Angular fluyen hacia abajo durante la detección de cambios.
|
||||||
Un componente primario puede cambiar fácilmente los valores en sus componentes secundarios porque primero se verifica el primario.
|
Un componente primario puede cambiar fácilmente los valores en sus componentes secundarios porque primero se verifica el primario.
|
||||||
Sin embargo, podría producirse un error si un componente secundario intenta cambiar un valor en su elemento primario durante la detección de cambio (invirtiendo el flujo de datos esperado), porque el componente principal ya se ha procesado.
|
Sin embargo, podría producirse un error si un componente secundario intenta cambiar un valor en su elemento primario durante la detección de cambio (invirtiendo el flujo de datos esperado), porque el componente principal ya se ha procesado.
|
||||||
En modo de desarrollo, Angular arroja el error `ExpressionChangedAfterItHasBeenCheckedError` si tu aplicación intenta hacer esto, en lugar de fallar silenciosamente en representar el nuevo valor.
|
En modo de desarrollo, Angular arroja el error `ExpressionChangedAfterItHasBeenCheckedError` si su aplicación intenta hacer esto, en lugar de fallar silenciosamente en representar el nuevo valor.
|
||||||
|
|
||||||
Para evitar este error, un método [lifecycle hook](guide/lifecycle-hooks) que busca realizar dicho cambio debería desencadenar una nueva ejecución de detección de cambio. La nueva ejecución sigue la misma dirección que antes, pero logra recoger el nuevo valor.
|
Para evitar este error, un método [lifecycle hook](guide/lifecycle-hooks)que busca realizar dicho cambio debería desencadenar una nueva ejecución de detección de cambio. La nueva ejecución sigue la misma dirección que antes, pero logra recoger el nuevo valor.
|
||||||
|
|
||||||
{@a G}
|
{@a G}
|
||||||
|
|
||||||
@ -508,10 +508,10 @@ Obtén más información en [Inyección de dependencia en Angular](guide/depende
|
|||||||
|
|
||||||
## interfaz de línea de comandos (CLI)
|
## interfaz de línea de comandos (CLI)
|
||||||
|
|
||||||
[Angular CLI](cli) es una herramienta de línea de comandos para administrar el ciclo de desarrollo Angular. Úsalo para crear la estructura inicial del sistema de archivos para un [espacio de trabajo](#workspace) o [proyecto](#project), y para ejecutar [esquemas](#schematic) que agreguen y modifiquen código para versiones genéricas iniciales de varios elementos. La CLI admite todas las etapas del ciclo de desarrollo, incluidas la construcción, las pruebas, la agrupación y la implementación.
|
[Angular CLI](cli) es una herramienta de línea de comandos para administrar el ciclo de desarrollo Angular. Úsalo para crear la estructura inicial del sistema de archivos para un [espacio de trabajo](#workspace) o [proyecto](#project), y para ejecutar [esquemas](#schematic) que agregue y modifique código para versiones genéricas iniciales de varios elementos. La CLI admite todas las etapas del ciclo de desarrollo, incluidas la construcción, las pruebas, la agrupación y la implementación.
|
||||||
|
|
||||||
- Para comenzar a usar la CLI para un nuevo proyecto, consulta [Configuración del entorno local](guide/setup-local "Configuración para el desarrollo local").
|
- Para comenzar a usar la CLI para un nuevo proyecto, consultá [Configuración del entorno local](guide/setup-local "Configuración para el desarrollo local").
|
||||||
- Para obtener más información sobre las capacidades completas de la CLI, consulta la [Referencia del comando CLI](cli).
|
- Para obtener más información sobre las capacidades completas de la CLI, consultá la [Referencia del comando CLI](cli).
|
||||||
|
|
||||||
Ver también [Esquemas CLI](#schematics-cli).
|
Ver también [Esquemas CLI](#schematics-cli).
|
||||||
|
|
||||||
@ -519,13 +519,13 @@ Ver también [Esquemas CLI](#schematics-cli).
|
|||||||
|
|
||||||
## inmutabilidad
|
## inmutabilidad
|
||||||
|
|
||||||
La capacidad de alterar el estado de un valor después de su creación. [Formularios reactivos](#reactive-forms) realizan cambios inmutables en ese cada cambio en el modelo de datos produce un nuevo modelo de datos en lugar de modificar el existente. [Formularios controlados por plantilla](#template-driven-forms) realizan cambios mutables con `NgModel` y [enlace de datos bidireccional](#data-binding) para modificar el modelo de datos existente en su lugar.
|
La capacidad de alterar el estado de un valor después de su creación. [Formularios reactivos](#reactive-forms) realizan cambios inmutables en ese cada cambio en el modelo de datos produce un nuevo modelo de datos en lugar de modificar el existente. [Formas controladas por plantilla](#template-driven-forms) realizan cambios mutables con `NgModel` y [enlace de datos bidireccional](#data-binding) para modificar el modelo de datos existente en su lugar.
|
||||||
|
|
||||||
{@a injectable}
|
{@a injectable}
|
||||||
|
|
||||||
## inyectable
|
## inyectable
|
||||||
|
|
||||||
Una clase Angular u otra definición que proporciona una dependencia utilizando el mecanismo de [inyección de dependencia](#di). Una clase inyectable de [servicio](#service) debe estar marcada por el [decorador](#decorator) `@Injectable()`. Otros elementos, como valores constantes, también pueden ser inyectables.
|
Una clase Angular u otra definición que proporciona una dependencia utilizando el mecanismo de [inyección de dependencia](#di). Una clase inyectable [servicio](#service) debe estar marcada por el `@Injectable()` [decorador](#decorator). Otros elementos, como valores constantes, también pueden ser inyectables.
|
||||||
|
|
||||||
{@a injector}
|
{@a injector}
|
||||||
|
|
||||||
@ -590,7 +590,7 @@ La jerarquía de vistas no implica una jerarquía de componentes. Las vistas que
|
|||||||
|
|
||||||
## lenguaje específico de dominio (DSL)
|
## lenguaje específico de dominio (DSL)
|
||||||
|
|
||||||
Una librería o API de propósito especial; consulte [lenguaje específico del dominio](https://es.wikipedia.org/wiki/Lenguaje_espec%C3%ADfico_de_dominio).
|
Una librería o API de propósito especial; consulte [Idioma específico del dominio](https://es.wikipedia.org/wiki/Lenguaje_espec%C3%ADfico_de_dominio).
|
||||||
Angular extiende TypeScript con lenguajes específicos de dominio para varios dominios relevantes para aplicaciones Angular, definidas en NgModules como [animaciones](guide/animations), [formularios](guide/forms), y [enrutamiento y navegación](guide/router).
|
Angular extiende TypeScript con lenguajes específicos de dominio para varios dominios relevantes para aplicaciones Angular, definidas en NgModules como [animaciones](guide/animations), [formularios](guide/forms), y [enrutamiento y navegación](guide/router).
|
||||||
|
|
||||||
{@a library}
|
{@a library}
|
||||||
@ -635,7 +635,7 @@ Obtén más información en [Lifecycle Hooks](guide/lifecycle-hooks).
|
|||||||
|
|
||||||
## modelo de formulario
|
## modelo de formulario
|
||||||
|
|
||||||
La "fuente de verdad" para el valor y el estado de validación de un elemento de entrada de formulario en un momento dado. Cuando se usan [formularios reactivos](#reactive-forms), el modelo de formulario se crea explícitamente en la clase de componente. Al utilizar [formularios controlados por plantilla](#template-driven-forms), el modelo de formulario se crea implícitamente mediante directivas.
|
La "fuente de verdad" para el valor y el estado de validación de un elemento de entrada de formulario en un momento dado. Cuando se usan [formularios reactivos](#reactive-forms), tel modelo de formulario se crea explícitamente en la clase de componente. Al utilizar [formularios controlados por plantilla](#template-driven-forms), el modelo de formulario se crea implícitamente mediante directivas.
|
||||||
|
|
||||||
Obtén más información sobre los formularios reactivos y basados en plantillas en [Introducción a los formularios en Angular](guide/forms-overview).
|
Obtén más información sobre los formularios reactivos y basados en plantillas en [Introducción a los formularios en Angular](guide/forms-overview).
|
||||||
|
|
||||||
@ -669,7 +669,7 @@ Una definición de clase precedida por el `@NgModule()` [decorador](#decorator),
|
|||||||
Al igual que un [módulo JavaScript](#module), un NgModule puede exportar la funcionalidad para que otros NgModules la usen e importar la funcionalidad pública de otros NgModules.
|
Al igual que un [módulo JavaScript](#module), un NgModule puede exportar la funcionalidad para que otros NgModules la usen e importar la funcionalidad pública de otros NgModules.
|
||||||
Los metadatos para una clase NgModule recopilan componentes, directivas y canalizaciones que la aplicación usa junto con la lista de importaciones y exportaciones. Ver también [declarable](#declarable).
|
Los metadatos para una clase NgModule recopilan componentes, directivas y canalizaciones que la aplicación usa junto con la lista de importaciones y exportaciones. Ver también [declarable](#declarable).
|
||||||
|
|
||||||
Los NgModules generalmente llevan el nombre del archivo en el que se define lo exportado. Por ejemplo, la clase [DatePipe](api/common/DatePipe) de Angular pertenece a un módulo de características llamado `date_pipe` en el archivo`date_pipe.ts`. Se importa desde un [paquete con scope](#scoped-package) como `@angular/core`.
|
Los NgModules generalmente llevan el nombre del archivo en el que se define lo exportado. Por ejemplo, la clase Angular [DatePipe](api/common/DatePipe) pertenece a un módulo de características llamado `date_pipe` en el archivo`date_pipe.ts`. Se importa desde un [paquete con scope](#scoped-package) como `@angular/core`.
|
||||||
|
|
||||||
Cada aplicación Angular tiene un módulo raíz. Por convención, la clase se llama `AppModule` y reside en un archivo llamado `app.module.ts`.
|
Cada aplicación Angular tiene un módulo raíz. Por convención, la clase se llama `AppModule` y reside en un archivo llamado `app.module.ts`.
|
||||||
|
|
||||||
@ -777,7 +777,7 @@ El archivo [`angular.json`](guide/workspace-config) configura todos los proyecto
|
|||||||
|
|
||||||
Una forma de insertar contenido DOM desde fuera de un componente en la vista del componente en un lugar designado.
|
Una forma de insertar contenido DOM desde fuera de un componente en la vista del componente en un lugar designado.
|
||||||
|
|
||||||
Para obtener más información, consulta [Respuesta a cambios en el contenido](guide/lifecycle-hooks#content-projection).
|
Para obtener más información, consultá [Respuesta a cambios en el contenido](guide/lifecycle-hooks#content-projection).
|
||||||
|
|
||||||
{@a provider}
|
{@a provider}
|
||||||
|
|
||||||
|
@ -28,7 +28,7 @@ Esto puede ayudar a evitar varias malas practicas o errores de arquitectura que
|
|||||||
|
|
||||||
Poniendo el código dentro de una librería separada es más complejo que simplemente poner todo en una sola aplicación.
|
Poniendo el código dentro de una librería separada es más complejo que simplemente poner todo en una sola aplicación.
|
||||||
Esto requiere una inversión mayor de tiempo y pensar para administrar, mantener y actualizar la librería.
|
Esto requiere una inversión mayor de tiempo y pensar para administrar, mantener y actualizar la librería.
|
||||||
Sin embargo esta complejidad puede valer la pena cuando la librería esta siendo usada en múltiples aplicaciones.
|
Sin embargo esta complejidad puede valer la pena cuando la librería esta siendo usada en multiples aplicaciones.
|
||||||
|
|
||||||
<div class="alert is-helpful">
|
<div class="alert is-helpful">
|
||||||
|
|
||||||
|
@ -1,56 +0,0 @@
|
|||||||
# Solution-style `tsconfig.json` migration
|
|
||||||
|
|
||||||
## What does this migration do?
|
|
||||||
|
|
||||||
This migration adds support to existing projects for TypeScript's new ["solution-style" tsconfig feature](https://devblogs.microsoft.com/typescript/announcing-typescript-3-9/#solution-style-tsconfig).
|
|
||||||
|
|
||||||
Support is added by making two changes:
|
|
||||||
|
|
||||||
1. Renaming the workspace-level `tsconfig.json` to `tsconfig.base.json`.
|
|
||||||
All project [TypeScript configuration files](guide/typescript-configuration) will extend from this base which contains the common options used throughout the workspace.
|
|
||||||
|
|
||||||
2. Adding the solution `tsconfig.json` file at the root of the workspace.
|
|
||||||
This `tsconfig.json` file will only contain references to project-level TypeScript configuration files and is only used by editors/IDEs.
|
|
||||||
|
|
||||||
As an example, the solution `tsconfig.json` for a new project is as follows:
|
|
||||||
|
|
||||||
```json
|
|
||||||
// This is a "Solution Style" tsconfig.json file, and is used by editors and TypeScript’s language server to improve development experience.
|
|
||||||
// It is not intended to be used to perform a compilation.
|
|
||||||
{
|
|
||||||
"files": [],
|
|
||||||
"references": [
|
|
||||||
{
|
|
||||||
"path": "./tsconfig.app.json"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"path": "./tsconfig.spec.json"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"path": "./e2e/tsconfig.json"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
## Why is this migration necessary?
|
|
||||||
|
|
||||||
Solution-style `tsconfig.json` files provide an improved editing experience and fix several long-standing defects when editing files in an IDE.
|
|
||||||
IDEs that leverage the TypeScript language service (for example, [Visual Studio Code](https://code.visualstudio.com)), will only use TypeScript configuration files that are named `tsconfig.json`.
|
|
||||||
In complex projects, there may be more than one compilation unit and each of these units may have different settings and options.
|
|
||||||
|
|
||||||
With the Angular CLI, a project will have application code that will target a browser.
|
|
||||||
It will also have unit tests that should not be included within the built application and that also need additional type information present (`jasmine` in this case).
|
|
||||||
Both parts of the project also share some but not all of the code within the project.
|
|
||||||
As a result, two separate TypeScript configuration files (`tsconfig.app.json` and `tsconfig.spec.json`) are needed to ensure that each part of the application is configured properly and that the right types are used for each part.
|
|
||||||
Also if web workers are used within a project, an additional tsconfig (`tsconfig.worker.json`) is needed.
|
|
||||||
Web workers use similar but incompatible types to the main browser application.
|
|
||||||
This requires the additional configuration file to ensure that the web worker files use the appropriate types and will build successfully.
|
|
||||||
|
|
||||||
While the Angular build system knows about all of these TypeScript configuration files, an IDE using TypeScript's language service does not.
|
|
||||||
Because of this, an IDE will not be able to properly analyze the code from each part of the project and may generate false errors or make suggestions that are incorrect for certain files.
|
|
||||||
By leveraging the new solution-style tsconfig, the IDE can now be aware of the configuration of each part of a project.
|
|
||||||
This allows each file to be treated appropriately based on its tsconfig.
|
|
||||||
IDE features such as error/warning reporting and auto-suggestion will operate more effectively as well.
|
|
||||||
|
|
||||||
The TypeScript 3.9 release [blog post](https://devblogs.microsoft.com/typescript/announcing-typescript-3-9/#solution-style-tsconfig) also contains some additional information regarding this new feature.
|
|
@ -1,20 +1,21 @@
|
|||||||
# Migrar el estilo de solución `tsconfig.json`
|
# Solution-style `tsconfig.json` migration
|
||||||
|
|
||||||
## ¿Qué hace esta migración?
|
## What does this migration do?
|
||||||
|
|
||||||
Esta migración agrega soporte a proyectos existentes la nueva funcionalidad de TypeScript ["estilo de solución" tsconfig](https://devblogs.microsoft.com/typescript/announcing-typescript-3-9/#solution-style-tsconfig).
|
This migration adds support to existing projects for TypeScript's new ["solution-style" tsconfig feature](https://devblogs.microsoft.com/typescript/announcing-typescript-3-9/#solution-style-tsconfig).
|
||||||
|
|
||||||
El soporte es agregado al realizar dos cambios:
|
Support is added by making two changes:
|
||||||
|
|
||||||
1. Renombrando el espacio de trabajo de `tsconfig.json` a `tsconfig.base.json`. Todos los [archivos de configuración de TypeScript](guide/typescript-configuration) se extenderán desde esta base que contiene las opciones comunes utilizadas en todo el espacio de trabajo.
|
1. Renaming the workspace-level `tsconfig.json` to `tsconfig.base.json`.
|
||||||
|
All project [TypeScript configuration files](guide/typescript-configuration) will extend from this base which contains the common options used throughout the workspace.
|
||||||
|
|
||||||
2. Agregando el archivo de solución `tsconfig.json` a la raíz del espacio de trabajo. Este archivo `tsconfig.json` solo contendrá referencias a archivos de configuración de TypeScript a nivel de proyecto y solo lo usarán editores/IDEs.
|
2. Adding the solution `tsconfig.json` file at the root of the workspace.
|
||||||
|
This `tsconfig.json` file will only contain references to project-level TypeScript configuration files and is only used by editors/IDEs.
|
||||||
Como ejemplo, la solución `tsconfig.json` para un nuevo proyecto es la siguiente:
|
|
||||||
|
|
||||||
|
As an example, the solution `tsconfig.json` for a new project is as follows:
|
||||||
```json
|
```json
|
||||||
// Este es un archivo "Estilo de Solución" tsconfig.json, y es usado por editores y servidores del lenguaje TypeScript para mejorar la experiencia de desarrollo.
|
// This is a "Solution Style" tsconfig.json file, and is used by editors and TypeScript’s language server to improve development experience.
|
||||||
// No está destinado para ser utilizado en la ejecución de una compilación
|
// It is not intended to be used to perform a compilation.
|
||||||
{
|
{
|
||||||
"files": [],
|
"files": [],
|
||||||
"references": [
|
"references": [
|
||||||
@ -31,24 +32,24 @@ Como ejemplo, la solución `tsconfig.json` para un nuevo proyecto es la siguient
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
## ¿Por qué es necesaria esta migración?
|
## Why is this migration necessary?
|
||||||
|
|
||||||
Los archivos de estilos de solución `tsconfig.json` brindan una experiencia de edición mejorada y corrigen varios defectos antiguos al editar archivos en un IDE.
|
Solution-style `tsconfig.json` files provide an improved editing experience and fix several long-standing defects when editing files in an IDE.
|
||||||
Los IDEs que aprovechan el servicio de lenguaje TypeScript (por ejemplo, [Visual Studio Code](https://code.visualstudio.com)), solo usarán archivos de configuración de TypeScript que se denominan `tsconfig.json`.
|
IDEs that leverage the TypeScript language service (for example, [Visual Studio Code](https://code.visualstudio.com)), will only use TypeScript configuration files that are named `tsconfig.json`.
|
||||||
En proyectos complejos, puede haber más de una unidad de compilación y cada una de estas unidades puede tener diferentes configuraciones y opciones.
|
In complex projects, there may be more than one compilation unit and each of these units may have different settings and options.
|
||||||
|
|
||||||
Con Angular CLI, un proyecto tendrá un código de la aplicación que tendrá como objetivo un navegador.
|
With the Angular CLI, a project will have application code that will target a browser.
|
||||||
También tendrá pruebas unitarias que no deben incluirse dentro de la aplicación construida y que también necesitan información adicional presente (`jasmine` en este caso).
|
It will also have unit tests that should not be included within the built application and that also need additional type information present (`jasmine` in this case).
|
||||||
Ambas partes del proyecto también comparten parte del código dentro del proyecto, pero no todo.
|
Both parts of the project also share some but not all of the code within the project.
|
||||||
Como resultado, se necesitan dos archivos de configuración TypeScript separados (`tsconfig.app.json` y `tsconfig.spec.json`) para garantizar que cada parte de la aplicación esté configurada correctamente y que se usen los tipos correctos para cada parte.
|
As a result, two separate TypeScript configuration files (`tsconfig.app.json` and `tsconfig.spec.json`) are needed to ensure that each part of the application is configured properly and that the right types are used for each part.
|
||||||
Además, si se utilizan web workers dentro de un proyecto, se necesita un tsconfig adicional (`tsconfig.worker.json`).
|
Also if web workers are used within a project, an additional tsconfig (`tsconfig.worker.json`) is needed.
|
||||||
Los web workers utilizan tipos similares pero incompatibles con la aplicación del navegador principal.
|
Web workers use similar but incompatible types to the main browser application.
|
||||||
Esto requiere el archivo de configuración adicional para garantizar que los archivos del web worker utilicen los tipos adecuados y se compilen correctamente.
|
This requires the additional configuration file to ensure that the web worker files use the appropriate types and will build successfully.
|
||||||
|
|
||||||
Mientras que el sistema de compilación Angular conoce todos estos archivos de configuración de TypeScript, un IDE que usa el servicio de lenguaje de TypeScript no los conoce.
|
While the Angular build system knows about all of these TypeScript configuration files, an IDE using TypeScript's language service does not.
|
||||||
Debido a esto, un IDE no podrá analizar correctamente el código de cada parte del proyecto y puede generar errores falsos o hacer sugerencias incorrectas para ciertos archivos.
|
Because of this, an IDE will not be able to properly analyze the code from each part of the project and may generate false errors or make suggestions that are incorrect for certain files.
|
||||||
Al aprovechar el nuevo estilo de solución tsconfig, el IDE ahora puede conocer la configuración de cada parte de un proyecto.
|
By leveraging the new solution-style tsconfig, the IDE can now be aware of the configuration of each part of a project.
|
||||||
Esto permite que cada archivo se trate de forma adecuada basado en su tsconfig.
|
This allows each file to be treated appropriately based on its tsconfig.
|
||||||
Las funcionalidades del IDE, como informes de error/advertencia y las sugerencias automáticas, también funcionarán de manera más eficaz.
|
IDE features such as error/warning reporting and auto-suggestion will operate more effectively as well.
|
||||||
|
|
||||||
La [publición en el blog](https://devblogs.microsoft.com/typescript/announcing-typescript-3-9/#solution-style-tsconfig) de la versión 3.9 de TypeScript contiene también información adicional sobre esta nueva funcionalidad.
|
The TypeScript 3.9 release [blog post](https://devblogs.microsoft.com/typescript/announcing-typescript-3-9/#solution-style-tsconfig) also contains some additional information regarding this new feature.
|
||||||
|
@ -1,33 +0,0 @@
|
|||||||
# Update `module` and `target` compiler options migration
|
|
||||||
|
|
||||||
## What does this migration do?
|
|
||||||
|
|
||||||
This migration adjusts the [`target`](https://www.typescriptlang.org/v2/en/tsconfig#target) and [`module`](https://www.typescriptlang.org/v2/en/tsconfig#module) settings within the [TypeScript configuration files](guide/typescript-configuration) for the workspace.
|
|
||||||
The changes to each option vary based on the builder or command that uses the TypeScript configuration file.
|
|
||||||
Unless otherwise noted, changes are only made if the existing value was not changed since the project was created.
|
|
||||||
This process helps ensure that intentional changes to the options are kept in place.
|
|
||||||
|
|
||||||
TypeScript Configuration File(s) | Changed Property | Existing Value | New Value
|
|
||||||
------------- | ------------- | ------------- | ------------- | -------------
|
|
||||||
`<workspace base>/tsconfig.base.json` | `"module"` | `"esnext"` | `"es2020"`
|
|
||||||
Used in `browser` builder options (`ng build` for applications) | `"module"` | `"esnext"` | `"es2020"`
|
|
||||||
Used in `ng-packgr` builder options (`ng build` for libraries) | `"module"` | `"esnext"` | `"es2020"`
|
|
||||||
Used in `karma` builder options (`ng test` for applications) | `"module"` | `"esnext"` | `"es2020"`
|
|
||||||
Used in `server` builder options (universal) | `"module"` | `"commonjs"` | _removed_
|
|
||||||
Used in `server` builder options (universal) | `"target"` | _any_ | `"es2016"`
|
|
||||||
Used in `protractor` builder options (`ng e2e` for applications) | `"target"` | `"es5"` | `"es2018"`
|
|
||||||
|
|
||||||
## Why is this migration necessary?
|
|
||||||
|
|
||||||
This migration provides improvements to the long-term supportability of projects by updating the projects to use recommended best practice compilation options.
|
|
||||||
|
|
||||||
For the functionality that executes on Node.js, such as Universal and Protractor, the new settings provide performance and troubleshooting benefits as well.
|
|
||||||
The minimum Node.js version for the Angular CLI (v10.13) supports features in ES2018 and earlier.
|
|
||||||
By targeting later ES versions, the compiler transforms less code and can use newer features directly.
|
|
||||||
Since zone.js does not support native `async` and `await`, the universal builds still target ES2016.
|
|
||||||
|
|
||||||
## Why `"es2020"` instead of `"esnext"`?
|
|
||||||
|
|
||||||
In TypeScript 3.9, the behavior of the TypeScript compiler controlled by `module` is the same with both `"esnext"` and `"es2020"` values.
|
|
||||||
This behavior can change in the future, because the `"esnext"` option could evolve in a backwards incompatible ways, resulting in build-time or run-time errors during a TypeScript update.
|
|
||||||
As a result, code can become unstable. Using the `"es2020"` option mitigates this risk.
|
|
@ -1,31 +1,33 @@
|
|||||||
# Actualizar las opciones del compilador `module` y `target` en la migración
|
# Update `module` and `target` compiler options migration
|
||||||
|
|
||||||
## ¿Qué hace esta migración?
|
## What does this migration do?
|
||||||
|
|
||||||
Esta migración ajusta la configuración de [`target`](https://www.typescriptlang.org/tsconfig#target) y [`module`](https://www.typescriptlang.org/v2/en/tsconfig#module) dentro de [los archivos de configuración de TypeScript](guide/typescript-configuration) para el espacio de trabajo.
|
This migration adjusts the [`target`](https://www.typescriptlang.org/v2/en/tsconfig#target) and [`module`](https://www.typescriptlang.org/v2/en/tsconfig#module) settings within the [TypeScript configuration files](guide/typescript-configuration) for the workspace.
|
||||||
Los cambios en cada opción varían según el constructor o comando que usa el archivo de configuración de TypeScript. A menos que se indique lo contrario, los cambios solo se realizan si el valor existente no se modificó desde que se creó el proyecto. Este proceso ayuda a garantizar que se mantengan los cambios intencionales en las opciones.
|
The changes to each option vary based on the builder or command that uses the TypeScript configuration file.
|
||||||
|
Unless otherwise noted, changes are only made if the existing value was not changed since the project was created.
|
||||||
|
This process helps ensure that intentional changes to the options are kept in place.
|
||||||
|
|
||||||
Archivo(s) de configuración de TypeScript | Propiedad Cambiada | Valor existente | Nuevo Valor
|
TypeScript Configuration File(s) | Changed Property | Existing Value | New Value
|
||||||
------------- | ------------- | ------------- | ------------- | -------------
|
------------- | ------------- | ------------- | ------------- | -------------
|
||||||
`<espacio de trabajo>/tsconfig.base.json` | `"module"` | `"esnext"` | `"es2020"`
|
`<workspace base>/tsconfig.base.json` | `"module"` | `"esnext"` | `"es2020"`
|
||||||
Utilizado en las opciones del constructor de `browser` (`ng build` para aplicaciones) | `"module"` | `"esnext"` | `"es2020"`
|
Used in `browser` builder options (`ng build` for applications) | `"module"` | `"esnext"` | `"es2020"`
|
||||||
Utilizado en las opciones del constructor de `ng-packgr` (`ng build` para librerías) | `"module"` | `"esnext"` | `"es2020"`
|
Used in `ng-packgr` builder options (`ng build` for libraries) | `"module"` | `"esnext"` | `"es2020"`
|
||||||
Utilizado en las opciones del constructor de `karma` (`ng test` para aplicaciones) | `"module"` | `"esnext"` | `"es2020"`
|
Used in `karma` builder options (`ng test` for applications) | `"module"` | `"esnext"` | `"es2020"`
|
||||||
Utilizado en las opciones (universales) del constructor de `server` | `"module"` | `"commonjs"` | _removed_
|
Used in `server` builder options (universal) | `"module"` | `"commonjs"` | _removed_
|
||||||
Utilizado en las opciones (universales) del constructor de `server` | `"target"` | _any_ | `"es2016"`
|
Used in `server` builder options (universal) | `"target"` | _any_ | `"es2016"`
|
||||||
Utilizado en las opciones del constructor de `protractor` (`ng e2e` para aplicaciones) | `"target"` | `"es5"` | `"es2018"`
|
Used in `protractor` builder options (`ng e2e` for applications) | `"target"` | `"es5"` | `"es2018"`
|
||||||
|
|
||||||
## ¿Por qué es necesaria esta migración?
|
## Why is this migration necessary?
|
||||||
|
|
||||||
Esta migración proporciona mejoras en la compatibilidad a largo plazo de los proyectos mediante la actualización de los proyectos utilizando las buenas prácticas recomendadas en las opciones de compilación.
|
This migration provides improvements to the long-term supportability of projects by updating the projects to use recommended best practice compilation options.
|
||||||
|
|
||||||
Para la funcionalidad que se ejecuta en Node.js, como Universal y Protractor, las nuevas configuraciones también brindan beneficios de rendimiento y resolución de problemas.
|
For the functionality that executes on Node.js, such as Universal and Protractor, the new settings provide performance and troubleshooting benefits as well.
|
||||||
La versión mínima de Node.js para Angular CLI (v10.13) admite funciones en ES2018 y versiones anteriores.
|
The minimum Node.js version for the Angular CLI (v10.13) supports features in ES2018 and earlier.
|
||||||
Al apuntar a versiones posteriores de ES, el compilador transforma menos código y puede usar funciones más nuevas directamente.
|
By targeting later ES versions, the compiler transforms less code and can use newer features directly.
|
||||||
Dado que zone.js no admite `async` y `await` de forma nativa, las compilaciones universales todavía apuntan a ES2016.
|
Since zone.js does not support native `async` and `await`, the universal builds still target ES2016.
|
||||||
|
|
||||||
## ¿Por qué `"es2020"` en lugar de `"esnext"`?
|
## Why `"es2020"` instead of `"esnext"`?
|
||||||
|
|
||||||
En TypeScript 3.9, el comportamiento del compilador TypeScript controlado por `module` es el mismo con los valores `"esnext"` y `"es2020"`.
|
In TypeScript 3.9, the behavior of the TypeScript compiler controlled by `module` is the same with both `"esnext"` and `"es2020"` values.
|
||||||
Este comportamiento puede cambiar en el futuro, porque la opción `"esnext"` podría evolucionar de manera incompatible hacia atrás, lo que resultaría en errores en tiempo de compilación o de ejecución durante una actualización de TypeScript.
|
This behavior can change in the future, because the `"esnext"` option could evolve in a backwards incompatible ways, resulting in build-time or run-time errors during a TypeScript update.
|
||||||
Como resultado, el código puede volverse inestable. El uso de la opción `"es2020"` mitiga este riesgo.
|
As a result, code can become unstable. Using the `"es2020"` option mitigates this risk.
|
||||||
|
@ -1,137 +0,0 @@
|
|||||||
# Workspace npm dependencies
|
|
||||||
|
|
||||||
The Angular Framework, Angular CLI, and components used by Angular applications are packaged as [npm packages](https://docs.npmjs.com/getting-started/what-is-npm "What is npm?") and distributed via the [npm registry](https://docs.npmjs.com/).
|
|
||||||
|
|
||||||
You can download and install these npm packages by using the [npm CLI client](https://docs.npmjs.com/cli/install), which is installed with and runs as a [Node.js®](https://nodejs.org "Nodejs.org") application. By default, the Angular CLI uses the npm client.
|
|
||||||
|
|
||||||
Alternatively, you can use the [yarn client](https://yarnpkg.com/) for downloading and installing npm packages.
|
|
||||||
|
|
||||||
|
|
||||||
<div class="alert is-helpful">
|
|
||||||
|
|
||||||
See [Local Environment Setup](guide/setup-local "Setting up for Local Development") for information about the required versions and installation of `Node.js` and `npm`.
|
|
||||||
|
|
||||||
If you already have projects running on your machine that use other versions of Node.js and npm, consider using [nvm](https://github.com/creationix/nvm) to manage the multiple versions of Node.js and npm.
|
|
||||||
|
|
||||||
</div>
|
|
||||||
|
|
||||||
|
|
||||||
## `package.json`
|
|
||||||
|
|
||||||
Both `npm` and `yarn` install the packages that are identified in a [`package.json`](https://docs.npmjs.com/files/package.json) file.
|
|
||||||
|
|
||||||
The CLI command `ng new` creates a `package.json` file when it creates the new workspace.
|
|
||||||
This `package.json` is used by all projects in the workspace, including the initial app project that is created by the CLI when it creates the workspace.
|
|
||||||
|
|
||||||
Initially, this `package.json` includes _a starter set of packages_, some of which are required by Angular and others that support common application scenarios.
|
|
||||||
You add packages to `package.json` as your application evolves.
|
|
||||||
You may even remove some.
|
|
||||||
|
|
||||||
The `package.json` is organized into two groups of packages:
|
|
||||||
|
|
||||||
* [Dependencies](guide/npm-packages#dependencies) are essential to *running* applications.
|
|
||||||
* [DevDependencies](guide/npm-packages#dev-dependencies) are only necessary to *develop* applications.
|
|
||||||
|
|
||||||
<div class="alert is-helpful">
|
|
||||||
|
|
||||||
**Library developers:** By default, the CLI command [`ng generate library`](cli/generate) creates a `package.json` for the new library. That `package.json` is used when publishing the library to npm.
|
|
||||||
For more information, see the CLI wiki page [Library Support](https://github.com/angular/angular-cli/wiki/stories-create-library).
|
|
||||||
</div>
|
|
||||||
|
|
||||||
|
|
||||||
{@a dependencies}
|
|
||||||
## Dependencies
|
|
||||||
|
|
||||||
The packages listed in the `dependencies` section of `package.json` are essential to *running* applications.
|
|
||||||
|
|
||||||
The `dependencies` section of `package.json` contains:
|
|
||||||
|
|
||||||
* [**Angular packages**](#angular-packages): Angular core and optional modules; their package names begin `@angular/`.
|
|
||||||
|
|
||||||
* [**Support packages**](#support-packages): 3rd party libraries that must be present for Angular apps to run.
|
|
||||||
|
|
||||||
* [**Polyfill packages**](#polyfills): Polyfills plug gaps in a browser's JavaScript implementation.
|
|
||||||
|
|
||||||
To add a new dependency, use the [`ng add`](cli/add) command.
|
|
||||||
|
|
||||||
{@a angular-packages}
|
|
||||||
### Angular packages
|
|
||||||
|
|
||||||
The following Angular packages are included as dependencies in the default `package.json` file for a new Angular workspace.
|
|
||||||
For a complete list of Angular packages, see the [API reference](http://angular.io/api?type=package).
|
|
||||||
|
|
||||||
Package name | Description
|
|
||||||
---------------------------------------- | --------------------------------------------------
|
|
||||||
[**@angular/animations**](api/animations) | Angular's animations library makes it easy to define and apply animation effects such as page and list transitions. For more information, see the [Animations guide](guide/animations).
|
|
||||||
[**@angular/common**](api/common) | The commonly-needed services, pipes, and directives provided by the Angular team. The [`HttpClientModule`](api/common/http/HttpClientModule) is also here, in the [`@angular/common/http`](api/common/http) subfolder. For more information, see the [HttpClient guide](guide/http).
|
|
||||||
**@angular/compiler** | Angular's template compiler. It understands templates and can convert them to code that makes the application run and render. Typically you don’t interact with the compiler directly; rather, you use it indirectly via `platform-browser-dynamic` when JIT compiling in the browser. For more information, see the [Ahead-of-time Compilation guide](guide/aot-compiler).
|
|
||||||
[**@angular/core**](api/core) | Critical runtime parts of the framework that are needed by every application. Includes all metadata decorators, `Component`, `Directive`, dependency injection, and the component lifecycle hooks.
|
|
||||||
[**@angular/forms**](api/forms) | Support for both [template-driven](guide/forms) and [reactive forms](guide/reactive-forms). For information about choosing the best forms approach for your app, see [Introduction to forms](guide/forms-overview).
|
|
||||||
[**@angular/<br />platform‑browser**](api/platform-browser) | Everything DOM and browser related, especially the pieces that help render into the DOM. This package also includes the `bootstrapModuleFactory()` method for bootstrapping applications for production builds that pre-compile with [AOT](guide/aot-compiler).
|
|
||||||
[**@angular/<br />platform‑browser‑dynamic**](api/platform-browser-dynamic) | Includes [providers](api/core/Provider) and methods to compile and run the app on the client using the [JIT compiler](guide/aot-compiler).
|
|
||||||
[**@angular/router**](api/router) | The router module navigates among your app pages when the browser URL changes. For more information, see [Routing and Navigation](guide/router).
|
|
||||||
|
|
||||||
|
|
||||||
{@a support-packages}
|
|
||||||
### Support packages
|
|
||||||
|
|
||||||
The following support packages are included as dependencies in the default `package.json` file for a new Angular workspace.
|
|
||||||
|
|
||||||
|
|
||||||
Package name | Description
|
|
||||||
---------------------------------------- | --------------------------------------------------
|
|
||||||
[**rxjs**](https://github.com/ReactiveX/rxjs) | Many Angular APIs return [_observables_](guide/glossary#observable). RxJS is an implementation of the proposed [Observables specification](https://github.com/tc39/proposal-observable) currently before the [TC39](https://www.ecma-international.org/memento/tc39.htm) committee, which determines standards for the JavaScript language.
|
|
||||||
[**zone.js**](https://github.com/angular/zone.js) | Angular relies on zone.js to run Angular's change detection processes when native JavaScript operations raise events. Zone.js is an implementation of a [specification](https://gist.github.com/mhevery/63fdcdf7c65886051d55) currently before the [TC39](https://www.ecma-international.org/memento/tc39.htm) committee that determines standards for the JavaScript language.
|
|
||||||
|
|
||||||
|
|
||||||
{@a polyfills}
|
|
||||||
### Polyfill packages
|
|
||||||
|
|
||||||
Many browsers lack native support for some features in the latest HTML standards,
|
|
||||||
features that Angular requires.
|
|
||||||
[_Polyfills_](https://en.wikipedia.org/wiki/Polyfill_(programming)) can emulate the missing features.
|
|
||||||
The [Browser Support](guide/browser-support) guide explains which browsers need polyfills and
|
|
||||||
how you can add them.
|
|
||||||
|
|
||||||
|
|
||||||
{@a dev-dependencies}
|
|
||||||
|
|
||||||
## DevDependencies
|
|
||||||
|
|
||||||
The packages listed in the `devDependencies` section of `package.json` help you develop the application on your local machine. You don't deploy them with the production application.
|
|
||||||
|
|
||||||
To add a new `devDependency`, use either one of the following commands:
|
|
||||||
|
|
||||||
<code-example language="sh" class="code-shell">
|
|
||||||
npm install --save-dev <package-name>
|
|
||||||
</code-example>
|
|
||||||
|
|
||||||
<code-example language="sh" class="code-shell">
|
|
||||||
yarn add --dev <package-name>
|
|
||||||
</code-example>
|
|
||||||
|
|
||||||
The following `devDependencies` are provided in the default `package.json` file for a new Angular workspace.
|
|
||||||
|
|
||||||
|
|
||||||
Package name | Description
|
|
||||||
---------------------------------------- | -----------------------------------
|
|
||||||
[**@angular‑devkit/<br />build‑angular**](https://github.com/angular/angular-cli/) | The Angular build tools.
|
|
||||||
[**@angular/cli**](https://github.com/angular/angular-cli/) | The Angular CLI tools.
|
|
||||||
**@angular/<br />compiler‑cli** | The Angular compiler, which is invoked by the Angular CLI's `ng build` and `ng serve` commands.
|
|
||||||
**@types/... ** | TypeScript definition files for 3rd party libraries such as Jasmine and Node.js.
|
|
||||||
[**codelyzer**](https://www.npmjs.com/package/codelyzer) | A linter for Angular apps whose rules conform to the Angular [style guide](guide/styleguide).
|
|
||||||
**jasmine/... ** | Packages to support the [Jasmine](https://jasmine.github.io/) test library.
|
|
||||||
**karma/... ** | Packages to support the [karma](https://www.npmjs.com/package/karma) test runner.
|
|
||||||
[**protractor**](https://www.npmjs.com/package/protractor) | An end-to-end (e2e) framework for Angular apps. Built on top of [WebDriverJS](https://github.com/SeleniumHQ/selenium/wiki/WebDriverJs).
|
|
||||||
[**ts-node**](https://www.npmjs.com/package/ts-node) | TypeScript execution environment and REPL for Node.js.
|
|
||||||
[**tslint**](https://www.npmjs.com/package/tslint) | A static analysis tool that checks TypeScript code for readability, maintainability, and functionality errors.
|
|
||||||
[**typescript**](https://www.npmjs.com/package/typescript) | The TypeScript language server, including the *tsc* TypeScript compiler.
|
|
||||||
|
|
||||||
|
|
||||||
## Related information
|
|
||||||
|
|
||||||
For information about how the Angular CLI handles packages see the following guides:
|
|
||||||
|
|
||||||
* [Building and serving](guide/build) describes how packages come together to create a development build.
|
|
||||||
* [Deployment](guide/deployment) describes how packages come together to create a production build.
|
|
||||||
|
|
@ -1,104 +1,106 @@
|
|||||||
# Área de trabajo de las dependencias de npm
|
# Workspace npm dependencies
|
||||||
|
|
||||||
El framework Angular, el CLI de Angular y los componentes usados por las aplicaciones Angular se empaquetan como [paquetes de npm](https://docs.npmjs.com/getting-started/what-is-npm "¿Qué es npm?") y se distribuyen a través del [registro de npm](https://docs.npmjs.com/).
|
The Angular Framework, Angular CLI, and components used by Angular applications are packaged as [npm packages](https://docs.npmjs.com/getting-started/what-is-npm "What is npm?") and distributed via the [npm registry](https://docs.npmjs.com/).
|
||||||
|
|
||||||
Puedes descargar e instalar esos paquetes de npm utilizando el [cliente CLI de npm](https://docs.npmjs.com/cli/install), el cuál se instala y ejecuta como una aplicación de [Node.js®](https://nodejs.org "Nodejs.org"). Por defecto el CLI de Angular utiliza el cliente de npm.
|
You can download and install these npm packages by using the [npm CLI client](https://docs.npmjs.com/cli/install), which is installed with and runs as a [Node.js®](https://nodejs.org "Nodejs.org") application. By default, the Angular CLI uses the npm client.
|
||||||
|
|
||||||
Alternativamente puedes utilizar el [cliente yarn](https://yarnpkg.com/) para descargar e instalar los paquetes de npm.
|
Alternatively, you can use the [yarn client](https://yarnpkg.com/) for downloading and installing npm packages.
|
||||||
|
|
||||||
|
|
||||||
<div class="alert is-helpful">
|
<div class="alert is-helpful">
|
||||||
|
|
||||||
Mira [Preparar Entorno Local](guide/setup-local "Preparándose para el desarrollo local") para ver información acerca de la instalación y las versiones requeridas de `Node.js` y `npm`.
|
See [Local Environment Setup](guide/setup-local "Setting up for Local Development") for information about the required versions and installation of `Node.js` and `npm`.
|
||||||
|
|
||||||
Si ya tenías proyectos anteriores en tu máquina que utilizan otras versiones de Node.js y npm considera usar [nvm](https://github.com/creationix/nvm) para gestionar las diferentes versiones de Node.js y npm.
|
If you already have projects running on your machine that use other versions of Node.js and npm, consider using [nvm](https://github.com/creationix/nvm) to manage the multiple versions of Node.js and npm.
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
||||||
## `package.json`
|
## `package.json`
|
||||||
|
|
||||||
Tanto `npm` como `yarn` instalan los paquetes que están identificados en un archivo [`package.json`](https://docs.npmjs.com/files/package.json).
|
Both `npm` and `yarn` install the packages that are identified in a [`package.json`](https://docs.npmjs.com/files/package.json) file.
|
||||||
|
|
||||||
El comando del CLI `ng new` genera un archivo `package.json` al crear el proyecto.
|
The CLI command `ng new` creates a `package.json` file when it creates the new workspace.
|
||||||
Este `package.json` es usado por todos los proyectos en el entorno incluyendo el proyecto inicial generado por el CLI al crear este entorno.
|
This `package.json` is used by all projects in the workspace, including the initial app project that is created by the CLI when it creates the workspace.
|
||||||
|
|
||||||
Inicialmente este `package.json` incluye _una serie de paquetes_, algunos de ellos necesarios para Angular y otros que soportan escenarios comunes de aplicación.
|
Initially, this `package.json` includes _a starter set of packages_, some of which are required by Angular and others that support common application scenarios.
|
||||||
Puedes añadir paquetes al `package.json` según tu aplicación crece.
|
You add packages to `package.json` as your application evolves.
|
||||||
También puedes borrarlos si es necesario.
|
You may even remove some.
|
||||||
|
|
||||||
El `package.json` se organiza en dos grupos de paquetes:
|
The `package.json` is organized into two groups of packages:
|
||||||
|
|
||||||
* [Dependencies](guide/npm-packages#dependencies) son necesarias para *ejecutar* aplicaciones.
|
* [Dependencies](guide/npm-packages#dependencies) are essential to *running* applications.
|
||||||
* [DevDependencies](guide/npm-packages#dev-dependencies) son solo necesarias para *desarrollar* aplicaciones.
|
* [DevDependencies](guide/npm-packages#dev-dependencies) are only necessary to *develop* applications.
|
||||||
|
|
||||||
<div class="alert is-helpful">
|
<div class="alert is-helpful">
|
||||||
|
|
||||||
**Desarrolladores de librerías:** Por defecto el comando de CLI [`ng generate library`](cli/generate) crea un `package.json` para la nueva librería. Ese `package.json` es usado cuando se publica la librería en npm.
|
**Library developers:** By default, the CLI command [`ng generate library`](cli/generate) creates a `package.json` for the new library. That `package.json` is used when publishing the library to npm.
|
||||||
Para más información leer [Creando librerías](guide/creating-libraries).
|
For more information, see the CLI wiki page [Library Support](https://github.com/angular/angular-cli/wiki/stories-create-library).
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
||||||
{@a dependencies}
|
{@a dependencies}
|
||||||
## Dependencies
|
## Dependencies
|
||||||
|
|
||||||
Los paquetes listados en la sección `dependencies` del `package.json` son esenciales para *ejecutar* aplicaciones.
|
The packages listed in the `dependencies` section of `package.json` are essential to *running* applications.
|
||||||
|
|
||||||
La sección `dependencies` del `package.json` contiene:
|
The `dependencies` section of `package.json` contains:
|
||||||
|
|
||||||
* [**Paquetes de Angular**](#angular-packages): El núcleo de Angular y módulos opcionales; el nombre de estos paquetes comienza por `@angular/`.
|
* [**Angular packages**](#angular-packages): Angular core and optional modules; their package names begin `@angular/`.
|
||||||
|
|
||||||
* [**Paquetes de soporte**](#support-packages): Librerías de terceros que son necesarias para que las aplicaciones de Angular se puedan ejecutar.
|
* [**Support packages**](#support-packages): 3rd party libraries that must be present for Angular apps to run.
|
||||||
|
|
||||||
* [**Paquetes de Polyfill**](#polyfills): Los Polyfills rellenan huecos en la implementación de Javascript de un navegador.
|
* [**Polyfill packages**](#polyfills): Polyfills plug gaps in a browser's JavaScript implementation.
|
||||||
|
|
||||||
Para añadir una nueva dependencia usa el comando [`ng add`](cli/add).
|
To add a new dependency, use the [`ng add`](cli/add) command.
|
||||||
|
|
||||||
{@a angular-packages}
|
{@a angular-packages}
|
||||||
### Paquetes de Angular
|
### Angular packages
|
||||||
|
|
||||||
Los siguientes paquetes de Angular se incluyen como dependencias en el archivo `package.json` por defecto en un nuevo proyecto de Angular.
|
The following Angular packages are included as dependencies in the default `package.json` file for a new Angular workspace.
|
||||||
Para ver la lista completa de paquetes de Angular visita la siguiente [referencia a la API](api?type=package).
|
For a complete list of Angular packages, see the [API reference](http://angular.io/api?type=package).
|
||||||
|
|
||||||
Nombre del Paquete | Descripción
|
Package name | Description
|
||||||
---------------------------------------- | --------------------------------------------------
|
---------------------------------------- | --------------------------------------------------
|
||||||
[**@angular/animations**](api/animations) | La librería de animaciones de Angular hace sencillo definir y aplicar efectos animados como transiciones de página y listas. Para más información visita [la guía de animaciones](guide/animations).
|
[**@angular/animations**](api/animations) | Angular's animations library makes it easy to define and apply animation effects such as page and list transitions. For more information, see the [Animations guide](guide/animations).
|
||||||
[**@angular/common**](api/common) | Los servicios comunes necesarios, pipes, y directivas proveídas por el equipo de Angular. El [`HttpClientModule`](api/common/http/HttpClientModule) también está aquí, en la subcarpeta [`@angular/common/http`](api/common/http). Para más información visita [la guía de HttpClient](guide/http).
|
[**@angular/common**](api/common) | The commonly-needed services, pipes, and directives provided by the Angular team. The [`HttpClientModule`](api/common/http/HttpClientModule) is also here, in the [`@angular/common/http`](api/common/http) subfolder. For more information, see the [HttpClient guide](guide/http).
|
||||||
**@angular/compiler** | El compilador de plantillas de Angular. Entiende las plantillas y las puede convertir a código que hace que la aplicación se ejecute y renderice. Habitualmente no interactúas con el compilador directamente; más bien lo usas indirectamente a través del `platform-browser-dynamic` cuando se compila en el navegador en tiempo de ejecución (JIT). Para más información visita [la guía de compilación AOT (Ahead-of-time)](guide/aot-compiler).
|
**@angular/compiler** | Angular's template compiler. It understands templates and can convert them to code that makes the application run and render. Typically you don’t interact with the compiler directly; rather, you use it indirectly via `platform-browser-dynamic` when JIT compiling in the browser. For more information, see the [Ahead-of-time Compilation guide](guide/aot-compiler).
|
||||||
[**@angular/core**](api/core) | Partes críticas del framework requeridas por cualquier aplicación en el tiempo de ejecución. Incluye todos los decoradores de los metadatos, `Componentes`, `Directivas`, inyección de dependencias y los ciclos de vida de los componentes.
|
[**@angular/core**](api/core) | Critical runtime parts of the framework that are needed by every application. Includes all metadata decorators, `Component`, `Directive`, dependency injection, and the component lifecycle hooks.
|
||||||
[**@angular/forms**](api/forms) | Soporte para formularios de tipo [template-driven](guide/forms) y [reactive forms](guide/reactive-forms). Para más información acerca de cuál es la mejor implementación de los formularios para tu aplicación visita [Introducción a los formularios](guide/forms-overview).
|
[**@angular/forms**](api/forms) | Support for both [template-driven](guide/forms) and [reactive forms](guide/reactive-forms). For information about choosing the best forms approach for your app, see [Introduction to forms](guide/forms-overview).
|
||||||
[**@angular/<br />platform‑browser**](api/platform-browser) | Todo lo relacionado con el DOM y el navegador, especialmente las piezas que ayudan a renderizar el DOM. Este paquete también incluye el método `bootstrapModuleFactory()` para cargar aplicaciones para builds de producción que pre-compilan con [AOT](guide/aot-compiler).
|
[**@angular/<br />platform‑browser**](api/platform-browser) | Everything DOM and browser related, especially the pieces that help render into the DOM. This package also includes the `bootstrapModuleFactory()` method for bootstrapping applications for production builds that pre-compile with [AOT](guide/aot-compiler).
|
||||||
[**@angular/<br />platform‑browser‑dynamic**](api/platform-browser-dynamic) | Incluye [providers](api/core/Provider) y métodos para compilar y ejecutar la aplicación en el cliente utilizando el [compilador JIT](guide/aot-compiler).
|
[**@angular/<br />platform‑browser‑dynamic**](api/platform-browser-dynamic) | Includes [providers](api/core/Provider) and methods to compile and run the app on the client using the [JIT compiler](guide/aot-compiler).
|
||||||
[**@angular/router**](api/router) | El módulo enrutador navega a través de las páginas de tu aplicación cuando la URL cambia. Para más información visita [Enrutado y Navegación](guide/router).
|
[**@angular/router**](api/router) | The router module navigates among your app pages when the browser URL changes. For more information, see [Routing and Navigation](guide/router).
|
||||||
|
|
||||||
|
|
||||||
{@a support-packages}
|
{@a support-packages}
|
||||||
### Paquetes de soporte
|
### Support packages
|
||||||
|
|
||||||
Los siguientes paquetes de soporte están incluidos como dependencias en el archivo `package.json` por defecto para un nuevo proyecto de Angular.
|
The following support packages are included as dependencies in the default `package.json` file for a new Angular workspace.
|
||||||
|
|
||||||
|
|
||||||
Nombre del Paquete | Descripción
|
Package name | Description
|
||||||
---------------------------------------- | --------------------------------------------------
|
---------------------------------------- | --------------------------------------------------
|
||||||
[**rxjs**](https://github.com/ReactiveX/rxjs) | Muchas APIs de Angular retornan [_observables_](guide/glossary#observable). RxJS es una implementación de la propuesta actual de [especificación de Observables](https://github.com/tc39/proposal-observable) antes del comité [TC39](https://www.ecma-international.org/memento/tc39.htm) que determina los estándares para el lenguaje JavaScript.
|
[**rxjs**](https://github.com/ReactiveX/rxjs) | Many Angular APIs return [_observables_](guide/glossary#observable). RxJS is an implementation of the proposed [Observables specification](https://github.com/tc39/proposal-observable) currently before the [TC39](https://www.ecma-international.org/memento/tc39.htm) committee, which determines standards for the JavaScript language.
|
||||||
[**zone.js**](https://github.com/angular/zone.js) | Angular depende de zone.js para ejecutar el proceso de detección de cambios de Angular cuando operaciones de JavaScript nativas lanzan eventos. Zone.js es una implementación actual de la [especificación](https://gist.github.com/mhevery/63fdcdf7c65886051d55) antes del comité [TC39](https://www.ecma-international.org/memento/tc39.htm) que determina los estándares para el lenguaje JavaScript.
|
[**zone.js**](https://github.com/angular/zone.js) | Angular relies on zone.js to run Angular's change detection processes when native JavaScript operations raise events. Zone.js is an implementation of a [specification](https://gist.github.com/mhevery/63fdcdf7c65886051d55) currently before the [TC39](https://www.ecma-international.org/memento/tc39.htm) committee that determines standards for the JavaScript language.
|
||||||
|
|
||||||
|
|
||||||
{@a polyfills}
|
{@a polyfills}
|
||||||
### Paquetes de Polyfill
|
### Polyfill packages
|
||||||
|
|
||||||
Muchos navegadores no tienen soporte de forma nativa para algunas funcionalidades de los últimos estándares de HTML, funcionalidades que Angular necesita.
|
Many browsers lack native support for some features in the latest HTML standards,
|
||||||
Los [_Polyfills_](https://en.wikipedia.org/wiki/Polyfill_(programming)) pueden emular las funcionalidades que falten.
|
features that Angular requires.
|
||||||
La guía de [soporte de navegador](guide/browser-support) explica qué navegadores necesitan polyfills y cómo los puedes añadir.
|
[_Polyfills_](https://en.wikipedia.org/wiki/Polyfill_(programming)) can emulate the missing features.
|
||||||
|
The [Browser Support](guide/browser-support) guide explains which browsers need polyfills and
|
||||||
|
how you can add them.
|
||||||
|
|
||||||
|
|
||||||
{@a dev-dependencies}
|
{@a dev-dependencies}
|
||||||
|
|
||||||
## DevDependencies
|
## DevDependencies
|
||||||
|
|
||||||
Los paquetes listados en la sección `devDependencies` del `package.json` te ayudan a desarrollar tu aplicación en tu ordenador. No necesitas desplegarla en un entorno de producción.
|
The packages listed in the `devDependencies` section of `package.json` help you develop the application on your local machine. You don't deploy them with the production application.
|
||||||
|
|
||||||
Para añadir una `devDependency` usa uno de los siguientes comandos:
|
To add a new `devDependency`, use either one of the following commands:
|
||||||
|
|
||||||
<code-example language="sh" class="code-shell">
|
<code-example language="sh" class="code-shell">
|
||||||
npm install --save-dev <package-name>
|
npm install --save-dev <package-name>
|
||||||
@ -108,28 +110,28 @@ Para añadir una `devDependency` usa uno de los siguientes comandos:
|
|||||||
yarn add --dev <package-name>
|
yarn add --dev <package-name>
|
||||||
</code-example>
|
</code-example>
|
||||||
|
|
||||||
Las siguientes `devDependencies` se proveen en el archivo `package.json` por defecto para un nuevo proyeto de Angular.
|
The following `devDependencies` are provided in the default `package.json` file for a new Angular workspace.
|
||||||
|
|
||||||
|
|
||||||
Nombre del Paquete | Descripción
|
Package name | Description
|
||||||
---------------------------------------- | -----------------------------------
|
---------------------------------------- | -----------------------------------
|
||||||
[**@angular‑devkit/<br />build‑angular**](https://github.com/angular/angular-cli/) | Las herramientas de creación de Angular.
|
[**@angular‑devkit/<br />build‑angular**](https://github.com/angular/angular-cli/) | The Angular build tools.
|
||||||
[**@angular/cli**](https://github.com/angular/angular-cli/) | Las herramientas del CLI de Angular.
|
[**@angular/cli**](https://github.com/angular/angular-cli/) | The Angular CLI tools.
|
||||||
**@angular/<br />compiler‑cli** | El compilador de Angular, el cual es invocado por el CLI de Angular mediante los comandos `ng build` y `ng serve`.
|
**@angular/<br />compiler‑cli** | The Angular compiler, which is invoked by the Angular CLI's `ng build` and `ng serve` commands.
|
||||||
**@types/... ** | Archivos Typescript de definición de librerías de terceros como Jasmine y Node.js.
|
**@types/... ** | TypeScript definition files for 3rd party libraries such as Jasmine and Node.js.
|
||||||
[**codelyzer**](https://www.npmjs.com/package/codelyzer) | Un linter para las aplicaciones de Angular con las reglas que conforman la [guía de estilos](guide/styleguide) de Angular.
|
[**codelyzer**](https://www.npmjs.com/package/codelyzer) | A linter for Angular apps whose rules conform to the Angular [style guide](guide/styleguide).
|
||||||
**jasmine/... ** | Paquetes para añadir soporte para la librería de testing [Jasmine](https://jasmine.github.io/).
|
**jasmine/... ** | Packages to support the [Jasmine](https://jasmine.github.io/) test library.
|
||||||
**karma/... ** | Paquetes para añadir soporte para el ejecutador de tests [karma](https://www.npmjs.com/package/karma).
|
**karma/... ** | Packages to support the [karma](https://www.npmjs.com/package/karma) test runner.
|
||||||
[**protractor**](https://www.npmjs.com/package/protractor) | Un framework end-to-end (e2e) para aplicaciones de Angular. Construido sobre [WebDriverJS](https://github.com/SeleniumHQ/selenium/wiki/WebDriverJs).
|
[**protractor**](https://www.npmjs.com/package/protractor) | An end-to-end (e2e) framework for Angular apps. Built on top of [WebDriverJS](https://github.com/SeleniumHQ/selenium/wiki/WebDriverJs).
|
||||||
[**ts-node**](https://www.npmjs.com/package/ts-node) | Entorno de ejecución de Typescript y REPL para Node.js.
|
[**ts-node**](https://www.npmjs.com/package/ts-node) | TypeScript execution environment and REPL for Node.js.
|
||||||
[**tslint**](https://www.npmjs.com/package/tslint) | Una herramienta de análisis estático de código que comprueba el código Typescript para que sea legible, mantenible y no contenga errores funcionales.
|
[**tslint**](https://www.npmjs.com/package/tslint) | A static analysis tool that checks TypeScript code for readability, maintainability, and functionality errors.
|
||||||
[**typescript**](https://www.npmjs.com/package/typescript) | El lenguaje de servidor Typescript, incluye el compilador de Typescript *tsc*.
|
[**typescript**](https://www.npmjs.com/package/typescript) | The TypeScript language server, including the *tsc* TypeScript compiler.
|
||||||
|
|
||||||
|
|
||||||
## Información relacionada
|
## Related information
|
||||||
|
|
||||||
Para obtener información acerca de cómo el CLI de Angular maneja los paquetes visita las siguientes guías:
|
For information about how the Angular CLI handles packages see the following guides:
|
||||||
|
|
||||||
* [Creando y sirviendo](guide/build) describe como los paquetes se unen para crear una build de desarrollo.
|
* [Building and serving](guide/build) describes how packages come together to create a development build.
|
||||||
* [Desplegando](guide/deployment) describe como los paquetes se unen para crear una build de producción.
|
* [Deployment](guide/deployment) describes how packages come together to create a production build.
|
||||||
|
|
@ -1,132 +0,0 @@
|
|||||||
# Route transition animations
|
|
||||||
|
|
||||||
#### Prerequisites
|
|
||||||
|
|
||||||
A basic understanding of the following concepts:
|
|
||||||
|
|
||||||
* [Introduction to Angular animations](guide/animations)
|
|
||||||
* [Transition and triggers](guide/transition-and-triggers)
|
|
||||||
* [Reusable animations](guide/reusable-animations)
|
|
||||||
|
|
||||||
<hr>
|
|
||||||
|
|
||||||
Routing enables users to navigate between different routes in an application. When a user navigates from one route to another, the Angular router maps the URL path to a relevant component and displays its view. Animating this route transition can greatly enhance the user experience.
|
|
||||||
|
|
||||||
The Angular router comes with high-level animation functions that let you animate the transitions between views when a route changes. To produce an animation sequence when switching between routes, you need to define nested animation sequences. Start with the top-level component that hosts the view, and nest additional animations in the components that host the embedded views.
|
|
||||||
|
|
||||||
To enable routing transition animation, do the following:
|
|
||||||
|
|
||||||
1. Import the routing module into the application and create a routing configuration that defines the possible routes.
|
|
||||||
2. Add a router outlet to tell the Angular router where to place the activated components in the DOM.
|
|
||||||
3. Define the animation.
|
|
||||||
|
|
||||||
|
|
||||||
Let's illustrate a router transition animation by navigating between two routes, *Home* and *About* associated with the `HomeComponent` and `AboutComponent` views respectively. Both of these component views are children of the top-most view, hosted by `AppComponent`. We'll implement a router transition animation that slides in the new view to the right and slides out the old view when the user navigates between the two routes.
|
|
||||||
|
|
||||||
</br>
|
|
||||||
|
|
||||||
<div class="lightbox">
|
|
||||||
<img src="generated/images/guide/animations/route-animation.gif" alt="Animations in action" width="440">
|
|
||||||
</div>
|
|
||||||
|
|
||||||
## Route configuration
|
|
||||||
|
|
||||||
To begin, configure a set of routes using methods available in the `RouterModule` class. This route configuration tells the router how to navigate.
|
|
||||||
|
|
||||||
Use the `RouterModule.forRoot` method to define a set of routes. Also, import this `RouterModule` to the `imports` array of the main module, `AppModule`.
|
|
||||||
|
|
||||||
<div class="alert is-helpful">
|
|
||||||
|
|
||||||
**Note:** Use the `RouterModule.forRoot` method in the root module, `AppModule`, to register top-level application routes and providers. For feature modules, call the `RouterModule.forChild` method to register additional routes.
|
|
||||||
|
|
||||||
</div>
|
|
||||||
|
|
||||||
The following configuration defines the possible routes for the application.
|
|
||||||
|
|
||||||
<code-example path="animations/src/app/app.module.ts" header="src/app/app.module.ts" region="route-animation-data" language="typescript"></code-example>
|
|
||||||
|
|
||||||
The `home` and `about` paths are associated with the `HomeComponent` and `AboutComponent` views. The route configuration tells the Angular router to instantiate the `HomeComponent` and `AboutComponent` views when the navigation matches the corresponding path.
|
|
||||||
|
|
||||||
In addition to `path` and `component`, the `data` property of each route defines the key animation-specific configuration associated with a route. The `data` property value is passed into `AppComponent` when the route changes. You can also pass additional data in route config that is consumed within the animation. The data property value has to match the transitions defined in the `routeAnimation` trigger, which we'll define later.
|
|
||||||
|
|
||||||
<div class="alert is-helpful">
|
|
||||||
|
|
||||||
**Note:** The `data` property names that you use can be arbitrary. For example, the name *animation* used in the example above is an arbitrary choice.
|
|
||||||
|
|
||||||
</div>
|
|
||||||
|
|
||||||
## Router outlet
|
|
||||||
|
|
||||||
After configuring the routes, tell the Angular router where to render the views when matched with a route. You can set a router outlet by inserting a `<router-outlet>` container inside the root `AppComponent` template.
|
|
||||||
|
|
||||||
The `<router-outlet>` container has an attribute directive that contains data about active routes and their states, based on the `data` property that we set in the route configuration.
|
|
||||||
|
|
||||||
<code-example path="animations/src/app/app.component.html" header="src/app/app.component.html" region="route-animations-outlet"></code-example>
|
|
||||||
|
|
||||||
`AppComponent` defines a method that can detect when a view changes. The method assigns an animation state value to the animation trigger (`@routeAnimation`) based on the route configuration `data` property value. Here's an example of an `AppComponent` method that detects when a route change happens.
|
|
||||||
|
|
||||||
<code-example path="animations/src/app/app.component.ts" header="src/app/app.component.ts" region="prepare-router-outlet" language="typescript"></code-example>
|
|
||||||
|
|
||||||
Here, the `prepareRoute()` method takes the value of the outlet directive (established through `#outlet="outlet"`) and returns a string value representing the state of the animation based on the custom data of the current active route. You can use this data to control which transition to execute for each route.
|
|
||||||
|
|
||||||
## Animation definition
|
|
||||||
|
|
||||||
Animations can be defined directly inside your components. For this example we are defining the animations in a separate file, which allows us to re-use the animations.
|
|
||||||
|
|
||||||
The following code snippet defines a reusable animation named `slideInAnimation`.
|
|
||||||
|
|
||||||
|
|
||||||
<code-example path="animations/src/app/animations.ts" header="src/app/animations.ts" region="route-animations" language="typescript"></code-example>
|
|
||||||
|
|
||||||
The animation definition does several things:
|
|
||||||
|
|
||||||
* Defines two transitions. A single trigger can define multiple states and transitions.
|
|
||||||
* Adjusts the styles of the host and child views to control their relative positions during the transition.
|
|
||||||
* Uses `query()` to determine which child view is entering and which is leaving the host view.
|
|
||||||
|
|
||||||
A route change activates the animation trigger, and a transition matching the state change is applied.
|
|
||||||
|
|
||||||
<div class="alert is-helpful">
|
|
||||||
|
|
||||||
**Note:** The transition states must match the `data` property value defined in the route configuration.
|
|
||||||
</div>
|
|
||||||
|
|
||||||
Make the animation definition available in your application by adding the reusable animation (`slideInAnimation`) to the `animations` metadata of the `AppComponent`.
|
|
||||||
|
|
||||||
<code-example path="animations/src/app/app.component.ts" header="src/app/app.component.ts" region="define" language="typescript"></code-example>
|
|
||||||
|
|
||||||
### Styling the host and child components
|
|
||||||
|
|
||||||
During a transition, a new view is inserted directly after the old one and both elements appear on screen at the same time. To prevent this, apply additional styling to the host view, and to the removed and inserted child views. The host view must use relative positioning, and the child views must use absolute positioning. Adding styling to the views animates the containers in place, without the DOM moving things around.
|
|
||||||
|
|
||||||
<code-example path="animations/src/app/animations.ts" header="src/app/animations.ts" region="style-view" language="typescript"></code-example>
|
|
||||||
|
|
||||||
### Querying the view containers
|
|
||||||
|
|
||||||
Use the `query()` method to find and animate elements within the current host component. The `query(":enter")` statement returns the view that is being inserted, and `query(":leave")` returns the view that is being removed.
|
|
||||||
|
|
||||||
Let's assume that we are routing from the *Home => About*.
|
|
||||||
|
|
||||||
<code-example path="animations/src/app/animations.ts" header="src/app/animations.ts (Continuation from above)" region="query" language="typescript"></code-example>
|
|
||||||
|
|
||||||
The animation code does the following after styling the views:
|
|
||||||
|
|
||||||
* `query(':enter', style({ left: '-100%' }))` matches the view that is added and hides the newly added view by positioning it to the far left.
|
|
||||||
* Calls `animateChild()` on the view that is leaving, to run its child animations.
|
|
||||||
* Uses `group()` function to make the inner animations run in parallel.
|
|
||||||
* Within the `group()` function:
|
|
||||||
* Queries the view that is removed and animates it to slide far to the right.
|
|
||||||
* Slides in the new view by animating the view with an easing function and duration. </br>
|
|
||||||
This animation results in the `about` view sliding from the left to right.
|
|
||||||
* Calls the `animateChild()` method on the new view to run its child animations after the main animation completes.
|
|
||||||
|
|
||||||
You now have a basic routable animation that animates routing from one view to another.
|
|
||||||
|
|
||||||
## More on Angular animations
|
|
||||||
|
|
||||||
You may also be interested in the following:
|
|
||||||
|
|
||||||
* [Introduction to Angular animations](guide/animations)
|
|
||||||
* [Transition and triggers](guide/transition-and-triggers)
|
|
||||||
* [Complex animation sequences](guide/complex-animation-sequences)
|
|
||||||
* [Reusable animations](guide/reusable-animations)
|
|
@ -1,26 +1,27 @@
|
|||||||
# Animaciones para transición de rutas
|
# Route transition animations
|
||||||
|
|
||||||
#### Prerrequisitos
|
#### Prerequisites
|
||||||
|
|
||||||
Una comprensión basica de los siguientes conceptos:
|
A basic understanding of the following concepts:
|
||||||
|
|
||||||
* [Introducción a animaciones en Angular](guide/animations)
|
* [Introduction to Angular animations](guide/animations)
|
||||||
* [Transición y desencadenadores](guide/transition-and-triggers)
|
* [Transition and triggers](guide/transition-and-triggers)
|
||||||
* [Animaciones reutilizables](guide/reusable-animations)
|
* [Reusable animations](guide/reusable-animations)
|
||||||
|
|
||||||
<hr>
|
<hr>
|
||||||
|
|
||||||
Enrutar permite a los usuarios navegar entre diferentes rutas de una aplicación. Cuando un usuario navega de una ruta a otra, el enrutador de Angular traza el trayecto de la URL a un componente importante y se muestra en su vista. Animar esta transición de rutas puede mejorar mucho la experiencia del usuario.
|
Routing enables users to navigate between different routes in an application. When a user navigates from one route to another, the Angular router maps the URL path to a relevant component and displays its view. Animating this route transition can greatly enhance the user experience.
|
||||||
|
|
||||||
El enrutador de Angular viene con funciones de animación de alto nivel que te permiten animar las transiciones entre vistas cuando una ruta cambia. Para producir una secuencia de animación al cambiar de ruta, necesitas definir secuencias de animación anidadas. Empieza con los componentes de alto nivel que contienen la vista, y anida animaciones adicionales en los componentes que contienen las vistas integradas.
|
The Angular router comes with high-level animation functions that let you animate the transitions between views when a route changes. To produce an animation sequence when switching between routes, you need to define nested animation sequences. Start with the top-level component that hosts the view, and nest additional animations in the components that host the embedded views.
|
||||||
|
|
||||||
Para permitir la animación de transición de rutas, haz lo siguiente:
|
To enable routing transition animation, do the following:
|
||||||
|
|
||||||
1. Importa el módulo enrutado dentro de la aplicación y crea una configuración de enrutamiento que defina las posibles rutas.
|
1. Import the routing module into the application and create a routing configuration that defines the possible routes.
|
||||||
2. Añade un punto de salida del enrutador para indicarle al enrutador de Angular donde posicionar los componentes activados en el DOM.
|
2. Add a router outlet to tell the Angular router where to place the activated components in the DOM.
|
||||||
3. Define la animación.
|
3. Define the animation.
|
||||||
|
|
||||||
Imaginemos un enrutador de animación de transiciones mediante la navegación entre dos rutas, *Home* y *About* asociadas con las vistas `HomeComponent` y `AboutComponent` respectivamente. Estos dos componentes de vista son hijos de la vista superior, contenida por `AppComponent`. Implementaremos un enrutador de animación de transiciones que desliza dentro la nueva vista hacia la derecha y desliza fuera la vista anterior cuando el usuario navega entre las dos rutas.
|
|
||||||
|
Let's illustrate a router transition animation by navigating between two routes, *Home* and *About* associated with the `HomeComponent` and `AboutComponent` views respectively. Both of these component views are children of the top-most view, hosted by `AppComponent`. We'll implement a router transition animation that slides in the new view to the right and slides out the old view when the user navigates between the two routes.
|
||||||
|
|
||||||
</br>
|
</br>
|
||||||
|
|
||||||
@ -28,104 +29,104 @@ Imaginemos un enrutador de animación de transiciones mediante la navegación en
|
|||||||
<img src="generated/images/guide/animations/route-animation.gif" alt="Animations in action" width="440">
|
<img src="generated/images/guide/animations/route-animation.gif" alt="Animations in action" width="440">
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
## Configuración de rutas
|
## Route configuration
|
||||||
|
|
||||||
Para empezar, configura un grupo de rutas usando los métodos disponibles en la clase `RouterModule`. Esta configuración de rutas le indica al enrutador cómo navegar.
|
To begin, configure a set of routes using methods available in the `RouterModule` class. This route configuration tells the router how to navigate.
|
||||||
|
|
||||||
Usa el método `RouterModule.forRoot` para definir un grupo de rutas. También, importa este `RouterModule` al array `imports` del módulo principal, `AppModule`.
|
Use the `RouterModule.forRoot` method to define a set of routes. Also, import this `RouterModule` to the `imports` array of the main module, `AppModule`.
|
||||||
|
|
||||||
<div class="alert is-helpful">
|
<div class="alert is-helpful">
|
||||||
|
|
||||||
**Nota:** Usa el método `RouterModule.forRoot` en el módulo raíz, `AppModule`, para registrar rutas y proveedores de nivel superior de la aplicación. Para los módulos de funcionalidad, llama el método `RouterModule.forChild` para registrar rutas adicionales.
|
**Note:** Use the `RouterModule.forRoot` method in the root module, `AppModule`, to register top-level application routes and providers. For feature modules, call the `RouterModule.forChild` method to register additional routes.
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
La siguiente configuración define las posibles rutas para la aplicación.
|
The following configuration defines the possible routes for the application.
|
||||||
|
|
||||||
<code-example path="animations/src/app/app.module.ts" header="src/app/app.module.ts" region="route-animation-data" language="typescript"></code-example>
|
<code-example path="animations/src/app/app.module.ts" header="src/app/app.module.ts" region="route-animation-data" language="typescript"></code-example>
|
||||||
|
|
||||||
Las rutas `home` y `about` están asociadas con las vistas `HomeComponent` y `AboutComponent`. La configuración de rutas le indica al enrutador de Angular que instancie las vistas `HomeComponent` y `AboutComponent` cuando la navegación coincide con la ruta correspondiente.
|
The `home` and `about` paths are associated with the `HomeComponent` and `AboutComponent` views. The route configuration tells the Angular router to instantiate the `HomeComponent` and `AboutComponent` views when the navigation matches the corresponding path.
|
||||||
|
|
||||||
A parte de `path` y `component`, la propiedad `data` de cada ruta define la configuración clave específica de la animación asociada con la ruta. El valor de la propiedad `data` se pasa a `AppComponent` cuando la ruta cambia. También puedes pasar datos adicionales en la configuración de la ruta que se consumen dentro de la animación. El valor de la propiedad data tiene que coincidir con las transiciones definidas en el desencadenador `routeAnimation`, que definiremos más adelante.
|
In addition to `path` and `component`, the `data` property of each route defines the key animation-specific configuration associated with a route. The `data` property value is passed into `AppComponent` when the route changes. You can also pass additional data in route config that is consumed within the animation. The data property value has to match the transitions defined in the `routeAnimation` trigger, which we'll define later.
|
||||||
|
|
||||||
<div class="alert is-helpful">
|
<div class="alert is-helpful">
|
||||||
|
|
||||||
**Nota:** Los nombres de las propiedades `data` que se utilizan pueden ser arbitrarios. Por ejemplo, el nombre *animación* utilizado en el ejemplo anterior es una elección arbitraria.
|
**Note:** The `data` property names that you use can be arbitrary. For example, the name *animation* used in the example above is an arbitrary choice.
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
## Punto de salida del enrutador
|
## Router outlet
|
||||||
|
|
||||||
Después de configurar las rutas, indícale al enrutador de Angular dónde renderizar las vistas cuando coincidan con una ruta. Puedes establecer un punto de salida del enrutador insertando un contenedor `<router-outlet>` dentro de la plantilla raíz `AppComponent`.
|
After configuring the routes, tell the Angular router where to render the views when matched with a route. You can set a router outlet by inserting a `<router-outlet>` container inside the root `AppComponent` template.
|
||||||
|
|
||||||
El contenedor `<router-outlet>` tiene una directiva de atributos que contiene datos sobre las rutas activas y sus estados, basados en la propiedad `data` que establecimos en la configuración de la ruta.
|
The `<router-outlet>` container has an attribute directive that contains data about active routes and their states, based on the `data` property that we set in the route configuration.
|
||||||
|
|
||||||
<code-example path="animations/src/app/app.component.html" header="src/app/app.component.html" region="route-animations-outlet"></code-example>
|
<code-example path="animations/src/app/app.component.html" header="src/app/app.component.html" region="route-animations-outlet"></code-example>
|
||||||
|
|
||||||
El `AppComponent` define un método que puede detectar cuando una vista cambia. El método asigna un valor de estado de animación al desencadenador de animación (`@routeAnimation`) basado en el valor de la propiedad `data` de configuración de la ruta. Aquí tienes un ejemplo de un método de `AppComponent` que detecta cuando se produce un cambio de ruta.
|
`AppComponent` defines a method that can detect when a view changes. The method assigns an animation state value to the animation trigger (`@routeAnimation`) based on the route configuration `data` property value. Here's an example of an `AppComponent` method that detects when a route change happens.
|
||||||
|
|
||||||
<code-example path="animations/src/app/app.component.ts" header="src/app/app.component.ts" region="prepare-router-outlet" language="typescript"></code-example>
|
<code-example path="animations/src/app/app.component.ts" header="src/app/app.component.ts" region="prepare-router-outlet" language="typescript"></code-example>
|
||||||
|
|
||||||
En este caso, el método `prepareRoute()` toma el valor de la directiva del punto de salida (establecido a través de `#outlet="outlet"`) y devuelve un valor de cadena que representa el estado de la animación basado en los datos personalizados de la ruta activa actual. Puedes utilizar estos datos para controlar qué transición ejecutar para cada ruta.
|
Here, the `prepareRoute()` method takes the value of the outlet directive (established through `#outlet="outlet"`) and returns a string value representing the state of the animation based on the custom data of the current active route. You can use this data to control which transition to execute for each route.
|
||||||
|
|
||||||
## Definición de la animación
|
## Animation definition
|
||||||
|
|
||||||
Las animaciones pueden ser definidas directamente dentro de tus componentes. Para este ejemplo estamos definiendo las animaciones en un archivo separado, lo que nos permite reutilizar las animaciones.
|
Animations can be defined directly inside your components. For this example we are defining the animations in a separate file, which allows us to re-use the animations.
|
||||||
|
|
||||||
|
The following code snippet defines a reusable animation named `slideInAnimation`.
|
||||||
|
|
||||||
El siguiente fragmento de código define una animación reutilizable llamada `slideInAnimation`.
|
|
||||||
|
|
||||||
<code-example path="animations/src/app/animations.ts" header="src/app/animations.ts" region="route-animations" language="typescript"></code-example>
|
<code-example path="animations/src/app/animations.ts" header="src/app/animations.ts" region="route-animations" language="typescript"></code-example>
|
||||||
|
|
||||||
La definición de animación hace varias cosas:
|
The animation definition does several things:
|
||||||
|
|
||||||
* Define dos transiciones. Un solo desencadenador puede definir múltiples estados y transiciones.
|
* Defines two transitions. A single trigger can define multiple states and transitions.
|
||||||
* Ajusta los estilos de las vistas anfitriona e hija para controlar sus posiciones relativas durante la transición.
|
* Adjusts the styles of the host and child views to control their relative positions during the transition.
|
||||||
* Utiliza `query()` para determinar qué vista hija está entrando y cuál está saliendo de la vista anfitriona.
|
* Uses `query()` to determine which child view is entering and which is leaving the host view.
|
||||||
|
|
||||||
Un cambio de ruta activa el desencadenante de la animación, y se aplica una transición que coincide con el cambio de estado.
|
A route change activates the animation trigger, and a transition matching the state change is applied.
|
||||||
|
|
||||||
<div class="alert is-helpful">
|
<div class="alert is-helpful">
|
||||||
|
|
||||||
**Nota:** Los estados de transición deben coincidir con el valor de la propiedad `data` definida en la configuración de la ruta.
|
**Note:** The transition states must match the `data` property value defined in the route configuration.
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
Haz que la definición de la animación esté disponible en tu aplicación añadiendo la animación reutilizable (`slideInAnimation`) a los metadatos `animations` del `AppComponent`.
|
Make the animation definition available in your application by adding the reusable animation (`slideInAnimation`) to the `animations` metadata of the `AppComponent`.
|
||||||
|
|
||||||
<code-example path="animations/src/app/app.component.ts" header="src/app/app.component.ts" region="define" language="typescript"></code-example>
|
<code-example path="animations/src/app/app.component.ts" header="src/app/app.component.ts" region="define" language="typescript"></code-example>
|
||||||
|
|
||||||
### Estilos de los componentes anfitrión e hijo
|
### Styling the host and child components
|
||||||
|
|
||||||
Durante una transición, se inserta una nueva vista directamente después de la anterior y ambos elementos aparecen en pantalla al mismo tiempo. Para evitarlo, aplica un estilo adicional a la vista anfitriona y a las vistas hijas eliminadas e insertadas. La vista anfitriona debe utilizar posicionamiento relativo, y las vistas hijas deben utilizar posicionamiento absoluto. Añadir estilos a las vistas anima los contenedores en su lugar, sin que el DOM mueva las cosas.
|
During a transition, a new view is inserted directly after the old one and both elements appear on screen at the same time. To prevent this, apply additional styling to the host view, and to the removed and inserted child views. The host view must use relative positioning, and the child views must use absolute positioning. Adding styling to the views animates the containers in place, without the DOM moving things around.
|
||||||
|
|
||||||
<code-example path="animations/src/app/animations.ts" header="src/app/animations.ts" region="style-view" language="typescript"></code-example>
|
<code-example path="animations/src/app/animations.ts" header="src/app/animations.ts" region="style-view" language="typescript"></code-example>
|
||||||
|
|
||||||
### Consultas de los contenedores de la vista
|
### Querying the view containers
|
||||||
|
|
||||||
Utiliza el método `query()` para encontrar y animar elementos dentro del componente anfitrión actual. La sentencia `query(":enter")` devuelve la vista que se está insertando, y `query(":leave")` devuelve la vista que se está eliminando.
|
Use the `query()` method to find and animate elements within the current host component. The `query(":enter")` statement returns the view that is being inserted, and `query(":leave")` returns the view that is being removed.
|
||||||
|
|
||||||
Supongamos que estamos enrutando desde *Home => About*.
|
Let's assume that we are routing from the *Home => About*.
|
||||||
|
|
||||||
<code-example path="animations/src/app/animations.ts" header="src/app/animations.ts (Continuation from above)" region="query" language="typescript"></code-example>
|
<code-example path="animations/src/app/animations.ts" header="src/app/animations.ts (Continuation from above)" region="query" language="typescript"></code-example>
|
||||||
|
|
||||||
El código de animación hace lo siguiente después de estilizar las vistas:
|
The animation code does the following after styling the views:
|
||||||
|
|
||||||
* `query(':enter', style({ left: '-100%' }))` coincide con la vista que se añade y oculta la nueva vista añadida posicionándola en el extremo izquierdo.
|
* `query(':enter', style({ left: '-100%' }))` matches the view that is added and hides the newly added view by positioning it to the far left.
|
||||||
* Llama a `animateChild()` en la vista que se va, para ejecutar las animaciones de sus hijos.
|
* Calls `animateChild()` on the view that is leaving, to run its child animations.
|
||||||
* Utiliza la función `group()` para hacer que las animaciones internas se ejecuten en paralelo.
|
* Uses `group()` function to make the inner animations run in parallel.
|
||||||
* Dentro de la función `group()`:
|
* Within the `group()` function:
|
||||||
* Consulta la vista que se elimina y la anima para que se deslice hacia la derecha.
|
* Queries the view that is removed and animates it to slide far to the right.
|
||||||
* Desliza la nueva vista animando la vista con una función de suavizado y duración. </br>
|
* Slides in the new view by animating the view with an easing function and duration. </br>
|
||||||
Esta animación hace que la vista `about` se deslice de izquierda a derecha.
|
This animation results in the `about` view sliding from the left to right.
|
||||||
* Llama al método `animateChild()` en la nueva vista para ejecutar sus animaciones hijas después de que la animación principal se complete.
|
* Calls the `animateChild()` method on the new view to run its child animations after the main animation completes.
|
||||||
|
|
||||||
Ahora tienes una animación básica que anima el enrutado de una vista a otra.
|
You now have a basic routable animation that animates routing from one view to another.
|
||||||
|
|
||||||
## Más información sobre las animaciones de Angular
|
## More on Angular animations
|
||||||
|
|
||||||
También puede interesarte lo siguiente:
|
You may also be interested in the following:
|
||||||
|
|
||||||
* [Introducción a las animaciones de Angular](guide/animations)
|
* [Introduction to Angular animations](guide/animations)
|
||||||
* [Transición y desencadenadores](guide/transition-and-triggers)
|
* [Transition and triggers](guide/transition-and-triggers)
|
||||||
* [Secuencias de animación complejas](guide/complex-animation-sequences)
|
* [Complex animation sequences](guide/complex-animation-sequences)
|
||||||
* [Animaciones reutilizables](guide/reusable-animations)
|
* [Reusable animations](guide/reusable-animations)
|
||||||
|
@ -1,97 +0,0 @@
|
|||||||
# The RxJS library
|
|
||||||
|
|
||||||
Reactive programming is an asynchronous programming paradigm concerned with data streams and the propagation of change ([Wikipedia](https://en.wikipedia.org/wiki/Reactive_programming)). RxJS (Reactive Extensions for JavaScript) is a library for reactive programming using observables that makes it easier to compose asynchronous or callback-based code. See ([RxJS Docs](https://rxjs.dev/guide/overview)).
|
|
||||||
|
|
||||||
RxJS provides an implementation of the `Observable` type, which is needed until the type becomes part of the language and until browsers support it. The library also provides utility functions for creating and working with observables. These utility functions can be used for:
|
|
||||||
|
|
||||||
* Converting existing code for async operations into observables
|
|
||||||
* Iterating through the values in a stream
|
|
||||||
* Mapping values to different types
|
|
||||||
* Filtering streams
|
|
||||||
* Composing multiple streams
|
|
||||||
|
|
||||||
## Observable creation functions
|
|
||||||
|
|
||||||
RxJS offers a number of functions that can be used to create new observables. These functions can simplify the process of creating observables from things such as events, timers, promises, and so on. For example:
|
|
||||||
|
|
||||||
|
|
||||||
<code-example path="rx-library/src/simple-creation.ts" region="promise" header="Create an observable from a promise"></code-example>
|
|
||||||
|
|
||||||
<code-example path="rx-library/src/simple-creation.ts" region="interval" header="Create an observable from a counter"></code-example>
|
|
||||||
|
|
||||||
<code-example path="rx-library/src/simple-creation.ts" region="event" header="Create an observable from an event"></code-example>
|
|
||||||
|
|
||||||
<code-example path="rx-library/src/simple-creation.ts" region="ajax" header="Create an observable that creates an AJAX request"></code-example>
|
|
||||||
|
|
||||||
## Operators
|
|
||||||
|
|
||||||
Operators are functions that build on the observables foundation to enable sophisticated manipulation of collections. For example, RxJS defines operators such as `map()`, `filter()`, `concat()`, and `flatMap()`.
|
|
||||||
|
|
||||||
Operators take configuration options, and they return a function that takes a source observable. When executing this returned function, the operator observes the source observable’s emitted values, transforms them, and returns a new observable of those transformed values. Here is a simple example:
|
|
||||||
|
|
||||||
<code-example path="rx-library/src/operators.ts" header="Map operator"></code-example>
|
|
||||||
|
|
||||||
You can use _pipes_ to link operators together. Pipes let you combine multiple functions into a single function. The `pipe()` function takes as its arguments the functions you want to combine, and returns a new function that, when executed, runs the composed functions in sequence.
|
|
||||||
|
|
||||||
A set of operators applied to an observable is a recipe—that is, a set of instructions for producing the values you’re interested in. By itself, the recipe doesn’t do anything. You need to call `subscribe()` to produce a result through the recipe.
|
|
||||||
|
|
||||||
Here’s an example:
|
|
||||||
|
|
||||||
<code-example path="rx-library/src/operators.1.ts" header="Standalone pipe function"></code-example>
|
|
||||||
|
|
||||||
The `pipe()` function is also a method on the RxJS `Observable`, so you use this shorter form to define the same operation:
|
|
||||||
|
|
||||||
<code-example path="rx-library/src/operators.2.ts" header="Observable.pipe function"></code-example>
|
|
||||||
|
|
||||||
### Common operators
|
|
||||||
|
|
||||||
RxJS provides many operators, but only a handful are used frequently. For a list of operators and usage samples, visit the [RxJS API Documentation](https://rxjs.dev/api).
|
|
||||||
|
|
||||||
<div class="alert is-helpful">
|
|
||||||
Note that, for Angular apps, we prefer combining operators with pipes, rather than chaining. Chaining is used in many RxJS examples.
|
|
||||||
</div>
|
|
||||||
|
|
||||||
| Area | Operators |
|
|
||||||
| :------------| :----------|
|
|
||||||
| Creation | `from`,`fromEvent`, `of` |
|
|
||||||
| Combination | `combineLatest`, `concat`, `merge`, `startWith` , `withLatestFrom`, `zip` |
|
|
||||||
| Filtering | `debounceTime`, `distinctUntilChanged`, `filter`, `take`, `takeUntil` |
|
|
||||||
| Transformation | `bufferTime`, `concatMap`, `map`, `mergeMap`, `scan`, `switchMap` |
|
|
||||||
| Utility | `tap` |
|
|
||||||
| Multicasting | `share` |
|
|
||||||
|
|
||||||
## Error handling
|
|
||||||
|
|
||||||
In addition to the `error()` handler that you provide on subscription, RxJS provides the `catchError` operator that lets you handle known errors in the observable recipe.
|
|
||||||
|
|
||||||
For instance, suppose you have an observable that makes an API request and maps to the response from the server. If the server returns an error or the value doesn’t exist, an error is produced. If you catch this error and supply a default value, your stream continues to process values rather than erroring out.
|
|
||||||
|
|
||||||
Here's an example of using the `catchError` operator to do this:
|
|
||||||
|
|
||||||
<code-example path="rx-library/src/error-handling.ts" header="catchError operator"></code-example>
|
|
||||||
|
|
||||||
### Retry failed observable
|
|
||||||
|
|
||||||
Where the `catchError` operator provides a simple path of recovery, the `retry` operator lets you retry a failed request.
|
|
||||||
|
|
||||||
Use the `retry` operator before the `catchError` operator. It resubscribes to the original source observable, which can then re-run the full sequence of actions that resulted in the error. If this includes an HTTP request, it will retry that HTTP request.
|
|
||||||
|
|
||||||
The following converts the previous example to retry the request before catching the error:
|
|
||||||
|
|
||||||
<code-example path="rx-library/src/retry-on-error.ts" header="retry operator"></code-example>
|
|
||||||
|
|
||||||
<div class="alert is-helpful">
|
|
||||||
|
|
||||||
Do not retry **authentication** requests, since these should only be initiated by user action. We don't want to lock out user accounts with repeated login requests that the user has not initiated.
|
|
||||||
|
|
||||||
</div>
|
|
||||||
|
|
||||||
## Naming conventions for observables
|
|
||||||
|
|
||||||
Because Angular applications are mostly written in TypeScript, you will typically know when a variable is an observable. Although the Angular framework does not enforce a naming convention for observables, you will often see observables named with a trailing “$” sign.
|
|
||||||
|
|
||||||
This can be useful when scanning through code and looking for observable values. Also, if you want a property to store the most recent value from an observable, it can be convenient to simply use the same name with or without the “$”.
|
|
||||||
|
|
||||||
For example:
|
|
||||||
|
|
||||||
<code-example path="rx-library/src/naming-convention.ts" header="Naming observables"></code-example>
|
|
@ -1,98 +1,97 @@
|
|||||||
# La Librería de RxJS
|
# The RxJS library
|
||||||
|
|
||||||
La programación Reactiva es un paradigma de programación asincrónico interesado en los flujos de datos y la propagación al cambio ([Wikipedia](https://en.wikipedia.org/wiki/Reactive_programming)). RxJS (Por sus siglas en Inglés, "Reactive Extensions for JavaScript") es una librería para programación reactiva usando obvservables que hacen más fácil la creación de código asincrono o basado en callbacks. Ver ([RxJS Docs](https://rxjs.dev/guide/overview)).
|
Reactive programming is an asynchronous programming paradigm concerned with data streams and the propagation of change ([Wikipedia](https://en.wikipedia.org/wiki/Reactive_programming)). RxJS (Reactive Extensions for JavaScript) is a library for reactive programming using observables that makes it easier to compose asynchronous or callback-based code. See ([RxJS Docs](https://rxjs.dev/guide/overview)).
|
||||||
|
|
||||||
RxJS proporciona una implementación del tipo `Observable`, el cual es necesitado hasta que el tipo de dato sea parte del lenguaje y hasta que los navegadores ofrezcan un soporte. La librería también proporciona funciones de utilería para la creación y trabajo con observables. Dichas funciones de utilería pueden ser usadas para:
|
RxJS provides an implementation of the `Observable` type, which is needed until the type becomes part of the language and until browsers support it. The library also provides utility functions for creating and working with observables. These utility functions can be used for:
|
||||||
|
|
||||||
* Convertir código existente para operaciones asíncronas en observables.
|
* Converting existing code for async operations into observables
|
||||||
* Iterar a través de valores en un flujo de datos.
|
* Iterating through the values in a stream
|
||||||
* Mappear valores en tipos de datos diferentes.
|
* Mapping values to different types
|
||||||
* Filtrar flujos de datos.
|
* Filtering streams
|
||||||
* Composición de múltiplos flujos.
|
* Composing multiple streams
|
||||||
|
|
||||||
## Creación de funciones observables
|
## Observable creation functions
|
||||||
|
|
||||||
RxJS ofrece un sin fin de funciones que pueden ser usadas para crear nuevos observables. Estas funciones pueden simplificar el proceso de creación de observables desde cosas como eventos, temporizadores, promesas, etc. Por ejemplo:
|
RxJS offers a number of functions that can be used to create new observables. These functions can simplify the process of creating observables from things such as events, timers, promises, and so on. For example:
|
||||||
|
|
||||||
<code-example path="rx-library/src/simple-creation.ts" region="promise" header="Crear un observable desde una promesa"></code-example>
|
|
||||||
|
|
||||||
<code-example path="rx-library/src/simple-creation.ts" region="interval" header="Crear un observable desde un contador"></code-example>
|
<code-example path="rx-library/src/simple-creation.ts" region="promise" header="Create an observable from a promise"></code-example>
|
||||||
|
|
||||||
<code-example path="rx-library/src/simple-creation.ts" region="event" header="Crear un observable desde un evento"></code-example>
|
<code-example path="rx-library/src/simple-creation.ts" region="interval" header="Create an observable from a counter"></code-example>
|
||||||
|
|
||||||
<code-example path="rx-library/src/simple-creation.ts" region="ajax" header="Crear un observable que crea una petición AJAX"></code-example>
|
<code-example path="rx-library/src/simple-creation.ts" region="event" header="Create an observable from an event"></code-example>
|
||||||
|
|
||||||
{@a operators}
|
<code-example path="rx-library/src/simple-creation.ts" region="ajax" header="Create an observable that creates an AJAX request"></code-example>
|
||||||
## Operadores
|
|
||||||
|
|
||||||
Los operadores son funciones que construyen sobre la fundación de los observables para tener una manipulación más sofisticada de las colecciones. Por ejemplo, RxJS define operadores como `map()`, `filter()`, `concat()`, y `flatMap()`.
|
## Operators
|
||||||
|
|
||||||
Los operadores toman las opciones de configuración y después regresan una función que toma la fuente observable. Cuando ejecutamos esta función regresada, el operador observa los valores fuente emitidos por el observable, los transforma y regresa un nuevo observable de esos valores transformados. Aquí un ejemplo sencillo:
|
Operators are functions that build on the observables foundation to enable sophisticated manipulation of collections. For example, RxJS defines operators such as `map()`, `filter()`, `concat()`, and `flatMap()`.
|
||||||
|
|
||||||
<code-example path="rx-library/src/operators.ts" header="Operador Map"></code-example>
|
Operators take configuration options, and they return a function that takes a source observable. When executing this returned function, the operator observes the source observable’s emitted values, transforms them, and returns a new observable of those transformed values. Here is a simple example:
|
||||||
|
|
||||||
Puedes usar _pipes_ para enlazar más de un operador. Los Pipes te permiten combinar múltiples funciones en una sola. La función `pipe()` tiene como argumentos las funciones que quieres que combine y regresa una nueva función que, una vez ejecutada, corre las funciones en una sequencia.
|
<code-example path="rx-library/src/operators.ts" header="Map operator"></code-example>
|
||||||
|
|
||||||
Un conjunto de operadores aplicados a un observable no es más que una receta la cuál, es un conjunto de instrucciones para producir los valores que te interesan. Por sí misma, esta receta no hace nada. Necesitarás llamar a la función `subscribe()` para producir un resultado a través dicha receta.
|
You can use _pipes_ to link operators together. Pipes let you combine multiple functions into a single function. The `pipe()` function takes as its arguments the functions you want to combine, and returns a new function that, when executed, runs the composed functions in sequence.
|
||||||
|
|
||||||
A continuación un ejemplo:
|
A set of operators applied to an observable is a recipe—that is, a set of instructions for producing the values you’re interested in. By itself, the recipe doesn’t do anything. You need to call `subscribe()` to produce a result through the recipe.
|
||||||
|
|
||||||
<code-example path="rx-library/src/operators.1.ts" header="Función pipe autónoma"></code-example>
|
Here’s an example:
|
||||||
|
|
||||||
La función `pipe()` es también un `Observable` en RxJS, así que usas esta manera más sencilla para definir la misma operación:
|
<code-example path="rx-library/src/operators.1.ts" header="Standalone pipe function"></code-example>
|
||||||
|
|
||||||
<code-example path="rx-library/src/operators.2.ts" header="Función Observable.pipe"></code-example>
|
The `pipe()` function is also a method on the RxJS `Observable`, so you use this shorter form to define the same operation:
|
||||||
|
|
||||||
### Operadores Comunes
|
<code-example path="rx-library/src/operators.2.ts" header="Observable.pipe function"></code-example>
|
||||||
|
|
||||||
RxJS propociona muchos operadores pero solo algunos se usan con frecuencia. Para una lista de los operadores y su uso visita la [Documentación de RxJS](https://rxjs.dev/api).
|
### Common operators
|
||||||
|
|
||||||
|
RxJS provides many operators, but only a handful are used frequently. For a list of operators and usage samples, visit the [RxJS API Documentation](https://rxjs.dev/api).
|
||||||
|
|
||||||
<div class="alert is-helpful">
|
<div class="alert is-helpful">
|
||||||
Nota: Para aplicaciones creadas con Angular preferiremos combinar operadores con pipes, en lugar de hacer cadenas. El encadenamiento es usado en muchos ejemplos de RxJS.
|
Note that, for Angular apps, we prefer combining operators with pipes, rather than chaining. Chaining is used in many RxJS examples.
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
| Area | Operador |
|
| Area | Operators |
|
||||||
| :------------| :----------|
|
| :------------| :----------|
|
||||||
| Creación | `from`,`fromEvent`, `of` |
|
| Creation | `from`,`fromEvent`, `of` |
|
||||||
| Combinación | `combineLatest`, `concat`, `merge`, `startWith` , `withLatestFrom`, `zip` |
|
| Combination | `combineLatest`, `concat`, `merge`, `startWith` , `withLatestFrom`, `zip` |
|
||||||
| Filtrado| `debounceTime`, `distinctUntilChanged`, `filter`, `take`, `takeUntil` |
|
| Filtering | `debounceTime`, `distinctUntilChanged`, `filter`, `take`, `takeUntil` |
|
||||||
| Transformación | `bufferTime`, `concatMap`, `map`, `mergeMap`, `scan`, `switchMap` |
|
| Transformation | `bufferTime`, `concatMap`, `map`, `mergeMap`, `scan`, `switchMap` |
|
||||||
| Utilería | `tap` |
|
| Utility | `tap` |
|
||||||
| Multidifusión | `share` |
|
| Multicasting | `share` |
|
||||||
|
|
||||||
## Manejo de Errores
|
## Error handling
|
||||||
|
|
||||||
En adición con el manejador de `error()` que te ayuda con la subscripción, RxJS proporciona el operador `catchError` que te permite manejar los errores conocidos en un medio de observables.
|
In addition to the `error()` handler that you provide on subscription, RxJS provides the `catchError` operator that lets you handle known errors in the observable recipe.
|
||||||
|
|
||||||
Por ejemplo, supongamos que tienes un observable que hace una petición a una API y mapea la respuesta de un servidor. Si el servidor regresa un error o el valor no existe entonces se produciría un error. Si hacemos un catch de este error y le proporcionamos un valor por defecto entonces el flujo continuará, en lugar de simplemente mandarnos un error.
|
For instance, suppose you have an observable that makes an API request and maps to the response from the server. If the server returns an error or the value doesn’t exist, an error is produced. If you catch this error and supply a default value, your stream continues to process values rather than erroring out.
|
||||||
|
|
||||||
|
Here's an example of using the `catchError` operator to do this:
|
||||||
|
|
||||||
Aquí un ejemplo de como usar el operador `catchError` para hacer esto:
|
<code-example path="rx-library/src/error-handling.ts" header="catchError operator"></code-example>
|
||||||
|
|
||||||
<code-example path="rx-library/src/error-handling.ts" header="Operador catchError"></code-example>
|
### Retry failed observable
|
||||||
|
|
||||||
### Observable de reintentos fallidos
|
Where the `catchError` operator provides a simple path of recovery, the `retry` operator lets you retry a failed request.
|
||||||
|
|
||||||
Donde el operador `catchError` ayuda a crear un camino simple para recuperarnos, el operador `retry` te permite reintentar una petición fallida.
|
Use the `retry` operator before the `catchError` operator. It resubscribes to the original source observable, which can then re-run the full sequence of actions that resulted in the error. If this includes an HTTP request, it will retry that HTTP request.
|
||||||
|
|
||||||
Usa el operador `retry` antes del operador `catchError`. Dicho operador te re-subscribe a la fuente original del observable, la cual puede re-ejecutar una secuencia llena de acciones que resultaron en el error en primer lugar. Si esto incluye una petición HTTP, entonces el operador reintentará hacer la petición HTTP.
|
The following converts the previous example to retry the request before catching the error:
|
||||||
|
|
||||||
En el siguiente ejemplo usamos el ejemplo anterior pero ahora intentamos hacer la petición primero antes de obtener el error.
|
<code-example path="rx-library/src/retry-on-error.ts" header="retry operator"></code-example>
|
||||||
|
|
||||||
<code-example path="rx-library/src/retry-on-error.ts" header="Operador retry"></code-example>
|
|
||||||
|
|
||||||
<div class="alert is-helpful">
|
<div class="alert is-helpful">
|
||||||
|
|
||||||
No intentar hacer peticiones con una **autenticación** , ya que estas deben ser inicialiadas por una acción del usuario. No nos gustaría bloquear cuentas de usuario con solicitudes de inicio de sesión repetidas que el mismo usuario no ha iniciado.
|
Do not retry **authentication** requests, since these should only be initiated by user action. We don't want to lock out user accounts with repeated login requests that the user has not initiated.
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
## Nombrando convenciones para los observables
|
## Naming conventions for observables
|
||||||
|
|
||||||
Debido a que en su mayoría las aplicaciones de Angular están escritas en TypeScript, típicamente sabrás cuando una variable es un observable. Aunque el framework de Angular no impone una convención de nombrado de observables, frecuentemente veras a los observables nombrados con el signo de “$” al final.
|
Because Angular applications are mostly written in TypeScript, you will typically know when a variable is an observable. Although the Angular framework does not enforce a naming convention for observables, you will often see observables named with a trailing “$” sign.
|
||||||
|
|
||||||
Esto puede llegar a ser muy útil cuando escaneamos rapidamente el código y miramos el valor de los observables. Además, si quieres tener una propiedad para almacenara el valor más reciente de un observable entonce puede ser muy conveniente simplemente usar el nombre con o sin el “$”.
|
This can be useful when scanning through code and looking for observable values. Also, if you want a property to store the most recent value from an observable, it can be convenient to simply use the same name with or without the “$”.
|
||||||
|
|
||||||
Por ejemplo:
|
For example:
|
||||||
|
|
||||||
<code-example path="rx-library/src/naming-convention.ts" header="Nombrando observables"></code-example>
|
<code-example path="rx-library/src/naming-convention.ts" header="Naming observables"></code-example>
|
||||||
|
@ -1,121 +0,0 @@
|
|||||||
# Generating code using schematics
|
|
||||||
|
|
||||||
A schematic is a template-based code generator that supports complex logic.
|
|
||||||
It is a set of instructions for transforming a software project by generating or modifying code.
|
|
||||||
Schematics are packaged into [collections](guide/glossary#collection) and installed with npm.
|
|
||||||
|
|
||||||
The schematic collection can be a powerful tool for creating, modifying, and maintaining any software project, but is particularly useful for customizing Angular projects to suit the particular needs of your own organization.
|
|
||||||
You might use schematics, for example, to generate commonly-used UI patterns or specific components, using predefined templates or layouts.
|
|
||||||
You can use schematics to enforce architectural rules and conventions, making your projects consistent and inter-operative.
|
|
||||||
|
|
||||||
## Schematics for the Angular CLI
|
|
||||||
|
|
||||||
Schematics are part of the Angular ecosystem. The [Angular CLI](guide/glossary#cli) uses schematics to apply transforms to a web-app project.
|
|
||||||
You can modify these schematics, and define new ones to do things like update your code to fix breaking changes in a dependency, for example, or to add a new configuration option or framework to an existing project.
|
|
||||||
|
|
||||||
Schematics that are included in the `@schematics/angular` collection are run by default by the commands `ng generate` and `ng add`.
|
|
||||||
The package contains named schematics that configure the options that are available to the CLI for `ng generate` sub-commands, such as `ng generate component` and `ng generate service`.
|
|
||||||
The subcommands for `ng generate` are shorthand for the corresponding schematic. You can specify a particular schematic (or collection of schematics) to generate, using the long form:
|
|
||||||
|
|
||||||
<code-example language="bash">
|
|
||||||
ng generate my-schematic-collection:my-schematic-name
|
|
||||||
</code-example>
|
|
||||||
|
|
||||||
or
|
|
||||||
|
|
||||||
<code-example language="bash">
|
|
||||||
ng generate my-schematic-name --collection collection-name
|
|
||||||
</code-example>
|
|
||||||
|
|
||||||
### Configuring CLI schematics
|
|
||||||
|
|
||||||
A JSON schema associated with a schematic tells the Angular CLI what options are available to commands and subcommands, and determines the defaults.
|
|
||||||
These defaults can be overridden by providing a different value for an option on the command line.
|
|
||||||
See [Workspace Configuration](guide/workspace-config) for information about how you can change the generation option defaults for your workspace.
|
|
||||||
|
|
||||||
The JSON schemas for the default schematics used by the CLI to generate projects and parts of projects are collected in the package [`@schematics/angular`](https://raw.githubusercontent.com/angular/angular-cli/v7.0.0/packages/schematics/angular/application/schema.json).
|
|
||||||
The schema describes the options available to the CLI for each of the `ng generate` sub-commands, as shown in the `--help` output.
|
|
||||||
|
|
||||||
## Developing schematics for libraries
|
|
||||||
|
|
||||||
As a library developer, you can create your own collections of custom schematics to integrate your library with the Angular CLI.
|
|
||||||
|
|
||||||
* An *add schematic* allows developers to install your library in an Angular workspace using `ng add`.
|
|
||||||
|
|
||||||
* *Generation schematics* can tell the `ng generate` subcommands how to modify projects, add configurations and scripts, and scaffold artifacts that are defined in your library.
|
|
||||||
|
|
||||||
* An *update schematic* can tell the `ng update` command how to update your library's dependencies and adjust for breaking changes when you release a new version.
|
|
||||||
|
|
||||||
For more details of what these look like and how to create them, see:
|
|
||||||
* [Authoring Schematics](guide/schematics-authoring)
|
|
||||||
* [Schematics for Libraries](guide/schematics-for-libraries)
|
|
||||||
|
|
||||||
### Add schematics
|
|
||||||
|
|
||||||
An add schematic is typically supplied with a library, so that the library can be added to an existing project with `ng add`.
|
|
||||||
The `add` command uses your package manager to download new dependencies, and invokes an installation script that is implemented as a schematic.
|
|
||||||
|
|
||||||
For example, the [`@angular/material`](https://material.angular.io/guide/schematics) schematic tells the `add` command to install and set up Angular Material and theming, and register new starter components that can be created with `ng generate`.
|
|
||||||
You can look at this one as an example and model for your own add schematic.
|
|
||||||
|
|
||||||
Partner and third party libraries also support the Angular CLI with add schematics.
|
|
||||||
For example, `@ng-bootstrap/schematics` adds [ng-bootstrap](https://ng-bootstrap.github.io/) to an app, and `@clr/angular` installs and sets up [Clarity from VMWare](https://vmware.github.io/clarity/documentation/v1.0/get-started).
|
|
||||||
|
|
||||||
An add schematic can also update a project with configuration changes, add additional dependencies (such as polyfills), or scaffold package-specific initialization code.
|
|
||||||
For example, the `@angular/pwa` schematic turns your application into a PWA by adding an app manifest and service worker, and the `@angular/elements` schematic adds the `document-register-element.js` polyfill and dependencies for Angular Elements.
|
|
||||||
|
|
||||||
### Generation schematics
|
|
||||||
|
|
||||||
Generation schematics are instructions for the `ng generate` command.
|
|
||||||
The documented sub-commands use the default Angular generation schematics, but you can specify a different schematic (in place of a sub-command) to generate an artifact defined in your library.
|
|
||||||
|
|
||||||
Angular Material, for example, supplies generation schematics for the UI components that it defines.
|
|
||||||
The following command uses one of these schematics to render an Angular Material `<mat-table>` that is pre-configured with a datasource for sorting and pagination.
|
|
||||||
|
|
||||||
<code-example language="bash">
|
|
||||||
ng generate @angular/material:table <component-name>
|
|
||||||
</code-example>
|
|
||||||
|
|
||||||
### Update schematics
|
|
||||||
|
|
||||||
The `ng update` command can be used to update your workspace's library dependencies. If you supply no options or use the help option, the command examines your workspace and suggests libraries to update.
|
|
||||||
|
|
||||||
<code-example language="bash">
|
|
||||||
ng update
|
|
||||||
We analyzed your package.json, there are some packages to update:
|
|
||||||
|
|
||||||
Name Version Command to update
|
|
||||||
--------------------------------------------------------------------------------
|
|
||||||
@angular/cdk 7.2.2 -> 7.3.1 ng update @angular/cdk
|
|
||||||
@angular/cli 7.2.3 -> 7.3.0 ng update @angular/cli
|
|
||||||
@angular/core 7.2.2 -> 7.2.3 ng update @angular/core
|
|
||||||
@angular/material 7.2.2 -> 7.3.1 ng update @angular/material
|
|
||||||
rxjs 6.3.3 -> 6.4.0 ng update rxjs
|
|
||||||
|
|
||||||
|
|
||||||
There might be additional packages that are outdated.
|
|
||||||
Run "ng update --all" to try to update all at the same time.
|
|
||||||
</code-example>
|
|
||||||
|
|
||||||
If you pass the command a set of libraries to update (or the `--all` flag), it updates those libraries, their peer dependencies, and the peer dependencies that depend on them.
|
|
||||||
|
|
||||||
<div class="alert is-helpful">
|
|
||||||
|
|
||||||
If there are inconsistencies (for example, if peer dependencies cannot be matched by a simple [semver](https://semver.io/) range), the command generates an error and does not change anything in the workspace.
|
|
||||||
|
|
||||||
We recommend that you do not force an update of all dependencies by default. Try updating specific dependencies first.
|
|
||||||
|
|
||||||
For more about how the `ng update` command works, see [Update Command](https://github.com/angular/angular-cli/blob/master/docs/specifications/update.md).
|
|
||||||
|
|
||||||
</div>
|
|
||||||
|
|
||||||
If you create a new version of your library that introduces potential breaking changes, you can provide an *update schematic* to enable the `ng update` command to automatically resolve any such changes in the project being updated.
|
|
||||||
|
|
||||||
For example, suppose you want to update the Angular Material library.
|
|
||||||
|
|
||||||
<code-example language="bash">
|
|
||||||
ng update @angular/material
|
|
||||||
</code-example>
|
|
||||||
|
|
||||||
This command updates both `@angular/material` and its dependency `@angular/cdk` in your workspace's `package.json`.
|
|
||||||
If either package contains an update schematic that covers migration from the existing version to a new version, the command runs that schematic on your workspace.
|
|
@ -1,97 +1,89 @@
|
|||||||
# Generando código usando esquemas
|
# Generating code using schematics
|
||||||
|
|
||||||
Un esquema es un generador de código basado en plantillas que soporta lógica compleja.
|
A schematic is a template-based code generator that supports complex logic.
|
||||||
Es un conjunto de instrucciones para transformar un proyecto de software, generando o modificando código.
|
It is a set of instructions for transforming a software project by generating or modifying code.
|
||||||
Los esquemas están en el paquete [collections](guide/glossary#collection) e instalados con npm.
|
Schematics are packaged into [collections](guide/glossary#collection) and installed with npm.
|
||||||
|
|
||||||
La colección de esquemas puede ser una herramienta poderosa para la creación, modificación, y mantenimiento de cualquier proyecto de software, pero es particularmente útil para personalizar proyectos de Angular de acuerdo a las necesidades de tu propia organización.
|
The schematic collection can be a powerful tool for creating, modifying, and maintaining any software project, but is particularly useful for customizing Angular projects to suit the particular needs of your own organization.
|
||||||
|
You might use schematics, for example, to generate commonly-used UI patterns or specific components, using predefined templates or layouts.
|
||||||
|
You can use schematics to enforce architectural rules and conventions, making your projects consistent and inter-operative.
|
||||||
|
|
||||||
Podrías utilizar esquemas, por ejemplo, para generar patrones UI o componentes específicos, usando templates o layouts.
|
## Schematics for the Angular CLI
|
||||||
Puedes usarlos también para hacer cumplir las reglas y convenciones arquitectónicas, haciendo que tus proyectos sean coherentes e inter operativos.
|
|
||||||
|
|
||||||
## Esquemas para Angular CLI
|
Schematics are part of the Angular ecosystem. The [Angular CLI](guide/glossary#cli) uses schematics to apply transforms to a web-app project.
|
||||||
|
You can modify these schematics, and define new ones to do things like update your code to fix breaking changes in a dependency, for example, or to add a new configuration option or framework to an existing project.
|
||||||
|
|
||||||
Los esquemas son parte del ecosistema de Angular, [Angular CLI](guide/glossary#cli) usa esquemas para aplicar transformaciones a proyectos web.
|
Schematics that are included in the `@schematics/angular` collection are run by default by the commands `ng generate` and `ng add`.
|
||||||
|
The package contains named schematics that configure the options that are available to the CLI for `ng generate` sub-commands, such as `ng generate component` and `ng generate service`.
|
||||||
Tu puedes modificar estos esquemas, y definir nuevos para hacer cosas como actualizar tu código para corregir cambios importantes en una dependencia, o para agregar una nueva opción de configuración o bien un framework a un proyecto existente.
|
The subcommands for `ng generate` are shorthand for the corresponding schematic. You can specify a particular schematic (or collection of schematics) to generate, using the long form:
|
||||||
|
|
||||||
Los esquemas que se incluyen en la colección `@schematics/angular` se ejecutan de forma predeterminada por los comandos `ng generate` y `ng add`.
|
|
||||||
|
|
||||||
El paquete contiene esquemas con nombre que configuran las opciones que están disponibles en el CLI para los subcomandos `ng generate`, por ejemplo `ng generate component` y `ng generate service`.
|
|
||||||
|
|
||||||
Los subcomandos para `ng generate` son una abreviatura para el schema correspondiente. Puedes especificar un esquema particular (o colección de esquemas) para generar, utilizando la forma larga:
|
|
||||||
|
|
||||||
<code-example language="bash">
|
<code-example language="bash">
|
||||||
ng generate my-schematic-collection:my-schematic-name
|
ng generate my-schematic-collection:my-schematic-name
|
||||||
</code-example>
|
</code-example>
|
||||||
|
|
||||||
o
|
or
|
||||||
|
|
||||||
<code-example language="bash">
|
<code-example language="bash">
|
||||||
ng generate my-schematic-name --collection collection-name
|
ng generate my-schematic-name --collection collection-name
|
||||||
</code-example>
|
</code-example>
|
||||||
|
|
||||||
### Configuración de esquemas de CLI
|
### Configuring CLI schematics
|
||||||
Un esquema JSON asociado con un esquema le dice a Angular CLI qué opciones están disponibles para comandos y subcomandos, y determina los valores predeterminados.
|
|
||||||
|
|
||||||
Estos valores predeterminados pueden ser sobrescritos para proporcionar un valor diferente para una opción en la línea de comandos.
|
A JSON schema associated with a schematic tells the Angular CLI what options are available to commands and subcommands, and determines the defaults.
|
||||||
Puede ver [Configuración del espacio de trabajo](guide/workspace-config) para obtener información de cómo puedes cambiar la opción de generación predeterminada para tu espacion de trabajo.
|
These defaults can be overridden by providing a different value for an option on the command line.
|
||||||
|
See [Workspace Configuration](guide/workspace-config) for information about how you can change the generation option defaults for your workspace.
|
||||||
|
|
||||||
Los esquemas JSON para los esquemas predeterminados que utiliza el CLI para generar proyectos y partes de proyectos están ubicados en el paquete [`@schematics/angular`](https://raw.githubusercontent.com/angular/angular-cli/v10.0.0/packages/schematics/angular/application/schema.json).
|
The JSON schemas for the default schematics used by the CLI to generate projects and parts of projects are collected in the package [`@schematics/angular`](https://raw.githubusercontent.com/angular/angular-cli/v7.0.0/packages/schematics/angular/application/schema.json).
|
||||||
|
The schema describes the options available to the CLI for each of the `ng generate` sub-commands, as shown in the `--help` output.
|
||||||
|
|
||||||
El esquema describe las opciones disponibles para el CLI para cada subcomando de `ng generate`, como se muestra en la salida de `--help`.
|
## Developing schematics for libraries
|
||||||
|
|
||||||
## Desarrollo de esquemas para librerías.
|
As a library developer, you can create your own collections of custom schematics to integrate your library with the Angular CLI.
|
||||||
|
|
||||||
Como desarrollador de librerías, puedes crear tus propias colecciones con esquemas personalizados para integrar tus librerías con Angular CLI.
|
* An *add schematic* allows developers to install your library in an Angular workspace using `ng add`.
|
||||||
|
|
||||||
* Un *add schematic* permite a los desarrolladores instalar sus librería en un espacion de trabajo de Angular usando `ng add`.
|
* *Generation schematics* can tell the `ng generate` subcommands how to modify projects, add configurations and scripts, and scaffold artifacts that are defined in your library.
|
||||||
|
|
||||||
* *Generation schematics* puede decirle a los subcomandos de `ng generate` como modificar proyectos, configuraciones, scripts y la estructura de artefactos que están definidos en su librería.
|
* An *update schematic* can tell the `ng update` command how to update your library's dependencies and adjust for breaking changes when you release a new version.
|
||||||
|
|
||||||
* Un *update schematic* puede decirle a los subcomandos de `ng update` como modificar las dependencias de las librerías y ajustarlos a los cambios importantes cuando lanza una nueva versión.
|
For more details of what these look like and how to create them, see:
|
||||||
|
* [Authoring Schematics](guide/schematics-authoring)
|
||||||
|
* [Schematics for Libraries](guide/schematics-for-libraries)
|
||||||
|
|
||||||
Para más detalles de cómo se ven y cómo crearlos, visitar.
|
### Add schematics
|
||||||
* [Esquemas de autoria](guide/schematics-authoring)
|
|
||||||
* [Esquemas para librerias](guide/schematics-for-libraries)
|
|
||||||
|
|
||||||
### Esquemas de adición
|
An add schematic is typically supplied with a library, so that the library can be added to an existing project with `ng add`.
|
||||||
|
The `add` command uses your package manager to download new dependencies, and invokes an installation script that is implemented as a schematic.
|
||||||
|
|
||||||
Un esquema de adición es típicamente suministrado por una librería, por lo que la librería puede ser agregado a un proyecto existente con `ng add`.
|
For example, the [`@angular/material`](https://material.angular.io/guide/schematics) schematic tells the `add` command to install and set up Angular Material and theming, and register new starter components that can be created with `ng generate`.
|
||||||
|
You can look at this one as an example and model for your own add schematic.
|
||||||
|
|
||||||
El comando `add` usa su administrador de paquetes para descargar una nueva dependencia, e invocar una script de instalación que es implementado como un schama.
|
Partner and third party libraries also support the Angular CLI with add schematics.
|
||||||
|
For example, `@ng-bootstrap/schematics` adds [ng-bootstrap](https://ng-bootstrap.github.io/) to an app, and `@clr/angular` installs and sets up [Clarity from VMWare](https://vmware.github.io/clarity/documentation/v1.0/get-started).
|
||||||
|
|
||||||
Por ejemplo, el esquema [`@angular/material`](https://material.angular.io/guide/schematics) le dice al comando `add` que instale y configure Angular Material junto con un tema, y que registre nuevos componentes que pueden ser creados con `ng generate`.
|
An add schematic can also update a project with configuration changes, add additional dependencies (such as polyfills), or scaffold package-specific initialization code.
|
||||||
|
For example, the `@angular/pwa` schematic turns your application into a PWA by adding an app manifest and service worker, and the `@angular/elements` schematic adds the `document-register-element.js` polyfill and dependencies for Angular Elements.
|
||||||
|
|
||||||
Puedes verlo como un ejemplo y modelo para tu propio esquema de adición.
|
### Generation schematics
|
||||||
|
|
||||||
Las librerías de terceros también soportan Angular CLI con esquemas de adición.
|
Generation schematics are instructions for the `ng generate` command.
|
||||||
|
The documented sub-commands use the default Angular generation schematics, but you can specify a different schematic (in place of a sub-command) to generate an artifact defined in your library.
|
||||||
|
|
||||||
Por ejemplo, `@ng-bootstrap/schematics` agrega [ng-bootstrap](https://ng-bootstrap.github.io/) para una aplicación, y `@clr/angular` instala y configura [Clarity from VMWare](https://clarity.design/get-started/developing/angular/).
|
Angular Material, for example, supplies generation schematics for the UI components that it defines.
|
||||||
|
The following command uses one of these schematics to render an Angular Material `<mat-table>` that is pre-configured with a datasource for sorting and pagination.
|
||||||
Un esquema de adición también puede actualizar un proyecto con cambios de configuración, agregar dependencias adicionales (así como polyfills), o estructurar código de inicialización específico del paquete.
|
|
||||||
|
|
||||||
Por ejemplo, el esquema `@angular/pwa` convierte tu aplicación en una PWA agregando un archivo manifest y un service worker, y el esquema `@angular/elements` agrega el `document-register-element.js` polyfill y dependencias para Angular Elements.
|
|
||||||
|
|
||||||
### Esquemas de Generación
|
|
||||||
Los esquemas de generación, son instrucciones para el comando `ng generate`.
|
|
||||||
Los sub comandos documentados usan esquemas de generación predeterminados de Angular, pero puedes especificar un esquema diferente (en lugar de un sub comando) para generar un artefacto definido en su librería.
|
|
||||||
|
|
||||||
Angular Material, por ejemplo, proporciona esquemas de generación para el componentes UI que los definen.
|
|
||||||
El siguiente comando usa uno de esos esquemas para renderizar Angular Material `<mat-table>` que es preconfigurado con un datasource para ordenar y paginar.
|
|
||||||
|
|
||||||
<code-example language="bash">
|
<code-example language="bash">
|
||||||
ng generate @angular/material:table <component-name>
|
ng generate @angular/material:table <component-name>
|
||||||
</code-example>
|
</code-example>
|
||||||
|
|
||||||
### Actualizar esquemas
|
### Update schematics
|
||||||
|
|
||||||
Los comandos `ng update` pueden ser usados para actualizar las dependencias de la librería de tu espacio de trabajo. Si no proporcionas opciones o usas la opción help, el comando examina tu espácio de trabajo y sugiere librerías para actualizar.
|
The `ng update` command can be used to update your workspace's library dependencies. If you supply no options or use the help option, the command examines your workspace and suggests libraries to update.
|
||||||
|
|
||||||
<code-example language="bash">
|
<code-example language="bash">
|
||||||
ng update
|
ng update
|
||||||
|
We analyzed your package.json, there are some packages to update:
|
||||||
|
|
||||||
Analizamos tu package.json, hay algunos paquetes por actualizar:
|
|
||||||
Name Version Command to update
|
Name Version Command to update
|
||||||
--------------------------------------------------------------------------------
|
--------------------------------------------------------------------------------
|
||||||
@angular/cdk 7.2.2 -> 7.3.1 ng update @angular/cdk
|
@angular/cdk 7.2.2 -> 7.3.1 ng update @angular/cdk
|
||||||
@ -100,29 +92,30 @@ ng update
|
|||||||
@angular/material 7.2.2 -> 7.3.1 ng update @angular/material
|
@angular/material 7.2.2 -> 7.3.1 ng update @angular/material
|
||||||
rxjs 6.3.3 -> 6.4.0 ng update rxjs
|
rxjs 6.3.3 -> 6.4.0 ng update rxjs
|
||||||
|
|
||||||
Es posible que haya paquetes adicionales que están actualizados.
|
|
||||||
Ejecutar "ng update --all" trata de actualizar todos los packages al mismo tiempo.
|
There might be additional packages that are outdated.
|
||||||
|
Run "ng update --all" to try to update all at the same time.
|
||||||
</code-example>
|
</code-example>
|
||||||
|
|
||||||
Si le pasas el comando un conjunto de librerías para actualizar (o la bandera `--all`), este actualiza esas librerías, sus dependencias de pares, y las dependencias de pares que dependen de ellos.
|
If you pass the command a set of libraries to update (or the `--all` flag), it updates those libraries, their peer dependencies, and the peer dependencies that depend on them.
|
||||||
|
|
||||||
<div class="alert is-helpful">
|
<div class="alert is-helpful">
|
||||||
|
|
||||||
Si hay inconsistencias (por ejemplo, si las dependencias de pares no coinciden con un simple rango [semver](https://semver.io/)), el comando genera un error y no cambia nada en el espacio de trabajo.
|
If there are inconsistencies (for example, if peer dependencies cannot be matched by a simple [semver](https://semver.io/) range), the command generates an error and does not change anything in the workspace.
|
||||||
|
|
||||||
Nosotros recomendamos que nos se force la actualización de todas la dependencias predeterminadas. Trata actualizando primero dependencias específicas.
|
We recommend that you do not force an update of all dependencies by default. Try updating specific dependencies first.
|
||||||
|
|
||||||
Para más información acerca del como trabaja el comando `ng update`, puedes vistar [Update Command](https://github.com/angular/angular-cli/blob/master/docs/specifications/update.md).
|
For more about how the `ng update` command works, see [Update Command](https://github.com/angular/angular-cli/blob/master/docs/specifications/update.md).
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
Si creas una nueva versión de tu librería que introduce cambios importantes, puedes proveer un *update schematic* para habilitar el comando `ng update` para automáticamente resolver cualquier cambio en un proyecto que se actualiza.
|
If you create a new version of your library that introduces potential breaking changes, you can provide an *update schematic* to enable the `ng update` command to automatically resolve any such changes in the project being updated.
|
||||||
|
|
||||||
Por ejemplo, supón que quieres actualizar la librería Angular Material.
|
For example, suppose you want to update the Angular Material library.
|
||||||
|
|
||||||
<code-example language="bash">
|
<code-example language="bash">
|
||||||
ng update @angular/material
|
ng update @angular/material
|
||||||
</code-example>
|
</code-example>
|
||||||
|
|
||||||
Este comando actualiza ambos `@angular/material` y sus dependencias `@angular/cdk` en tu espacion de trabajo `package.json`.
|
This command updates both `@angular/material` and its dependency `@angular/cdk` in your workspace's `package.json`.
|
||||||
Si alguno de los paquetes contiene un esquema de actualización que cubre la migración de una versión existente hacia una nueva versión, el comando ejecuta ese esquema en su espacio de trabajo.
|
If either package contains an update schematic that covers migration from the existing version to a new version, the command runs that schematic on your workspace.
|
||||||
|
@ -1,84 +0,0 @@
|
|||||||
# Angular service worker introduction
|
|
||||||
|
|
||||||
Service workers augment the traditional web deployment model and empower applications to deliver a user experience with the reliability and performance on par with natively-installed code. Adding a service worker to an Angular application is one of the steps for turning an application into a [Progressive Web App](https://developers.google.com/web/progressive-web-apps/) (also known as a PWA).
|
|
||||||
|
|
||||||
At its simplest, a service worker is a script that runs in the web browser and manages caching for an application.
|
|
||||||
|
|
||||||
Service workers function as a network proxy. They intercept all outgoing HTTP requests made by the application and can choose how to respond to them. For example, they can query a local cache and deliver a cached response if one is available. Proxying isn't limited to requests made through programmatic APIs, such as `fetch`; it also includes resources referenced in HTML and even the initial request to `index.html`. Service worker-based caching is thus completely programmable and doesn't rely on server-specified caching headers.
|
|
||||||
|
|
||||||
Unlike the other scripts that make up an application, such as the Angular app bundle, the service worker is preserved after the user closes the tab. The next time that browser loads the application, the service worker loads first, and can intercept every request for resources to load the application. If the service worker is designed to do so, it can *completely satisfy the loading of the application, without the need for the network*.
|
|
||||||
|
|
||||||
Even across a fast reliable network, round-trip delays can introduce significant latency when loading the application. Using a service worker to reduce dependency on the network can significantly improve the user experience.
|
|
||||||
|
|
||||||
|
|
||||||
## Service workers in Angular
|
|
||||||
|
|
||||||
Angular applications, as single-page applications, are in a prime position to benefit from the advantages of service workers. Starting with version 5.0.0, Angular ships with a service worker implementation. Angular developers can take advantage of this service worker and benefit from the increased reliability and performance it provides, without needing to code against low-level APIs.
|
|
||||||
|
|
||||||
Angular's service worker is designed to optimize the end user experience of using an application over a slow or unreliable network connection, while also minimizing the risks of serving outdated content.
|
|
||||||
|
|
||||||
The Angular service worker's behavior follows that design goal:
|
|
||||||
|
|
||||||
* Caching an application is like installing a native application. The application is cached as one unit, and all files update together.
|
|
||||||
* A running application continues to run with the same version of all files. It does not suddenly start receiving cached files from a newer version, which are likely incompatible.
|
|
||||||
* When users refresh the application, they see the latest fully cached version. New tabs load the latest cached code.
|
|
||||||
* Updates happen in the background, relatively quickly after changes are published. The previous version of the application is served until an update is installed and ready.
|
|
||||||
* The service worker conserves bandwidth when possible. Resources are only downloaded if they've changed.
|
|
||||||
|
|
||||||
To support these behaviors, the Angular service worker loads a *manifest* file from the server. The manifest describes the resources to cache and includes hashes of every file's contents. When an update to the application is deployed, the contents of the manifest change, informing the service worker that a new version of the application should be downloaded and cached. This manifest is generated from a CLI-generated configuration file called `ngsw-config.json`.
|
|
||||||
|
|
||||||
Installing the Angular service worker is as simple as including an `NgModule`. In addition to registering the Angular service worker with the browser, this also makes a few services available for injection which interact with the service worker and can be used to control it. For example, an application can ask to be notified when a new update becomes available, or an application can ask the service worker to check the server for available updates.
|
|
||||||
|
|
||||||
## Prerequisites
|
|
||||||
|
|
||||||
To make use of all the features of Angular service worker, use the latest versions of Angular and the Angular CLI.
|
|
||||||
|
|
||||||
In order for service workers to be registered, the app must be accessed over HTTPS, not HTTP.
|
|
||||||
Browsers ignore service workers on pages that are served over an insecure connection.
|
|
||||||
The reason is that service workers are quite powerful, so extra care needs to be taken to ensure the service worker script has not been tampered with.
|
|
||||||
|
|
||||||
There is one exception to this rule: to make local development easier, browsers do _not_ require a secure connection when accessing an app on `localhost`.
|
|
||||||
|
|
||||||
### Browser support
|
|
||||||
|
|
||||||
To benefit from the Angular service worker, your app must run in a web browser that supports service workers in general.
|
|
||||||
Currently, service workers are supported in the latest versions of Chrome, Firefox, Edge, Safari, Opera, UC Browser (Android version) and Samsung Internet.
|
|
||||||
Browsers like IE and Opera Mini do not support service workers.
|
|
||||||
|
|
||||||
If the user is accessing your app via a browser that does not support service workers, the service worker is not registered and related behavior such as offline cache management and push notifications does not happen.
|
|
||||||
More specifically:
|
|
||||||
|
|
||||||
* The browser does not download the service worker script and `ngsw.json` manifest file.
|
|
||||||
* Active attempts to interact with the service worker, such as calling `SwUpdate.checkForUpdate()`, return rejected promises.
|
|
||||||
* The observable events of related services, such as `SwUpdate.available`, are not triggered.
|
|
||||||
|
|
||||||
It is highly recommended that you ensure that your app works even without service worker support in the browser.
|
|
||||||
Although an unsupported browser ignores service worker caching, it will still report errors if the app attempts to interact with the service worker.
|
|
||||||
For example, calling `SwUpdate.checkForUpdate()` will return rejected promises.
|
|
||||||
To avoid such an error, you can check whether the Angular service worker is enabled using `SwUpdate.isEnabled()`.
|
|
||||||
|
|
||||||
To learn more about other browsers that are service worker ready, see the [Can I Use](https://caniuse.com/#feat=serviceworkers) page and [MDN docs](https://developer.mozilla.org/en-US/docs/Web/API/Service_Worker_API).
|
|
||||||
|
|
||||||
|
|
||||||
## Related resources
|
|
||||||
|
|
||||||
The rest of the articles in this section specifically address the Angular implementation of service workers.
|
|
||||||
|
|
||||||
* [App Shell](guide/app-shell)
|
|
||||||
* [Service Worker Communication](guide/service-worker-communications)
|
|
||||||
* [Service Worker in Production](guide/service-worker-devops)
|
|
||||||
* [Service Worker Configuration](guide/service-worker-config)
|
|
||||||
|
|
||||||
For more information about service workers in general, see [Service Workers: an Introduction](https://developers.google.com/web/fundamentals/primers/service-workers/).
|
|
||||||
|
|
||||||
For more information about browser support, see the [browser support](https://developers.google.com/web/fundamentals/primers/service-workers/#browser_support) section of [Service Workers: an Introduction](https://developers.google.com/web/fundamentals/primers/service-workers/), Jake Archibald's [Is Serviceworker ready?](https://jakearchibald.github.io/isserviceworkerready/), and
|
|
||||||
[Can I Use](http://caniuse.com/#feat=serviceworkers).
|
|
||||||
|
|
||||||
For additional recommendations and examples, see:
|
|
||||||
|
|
||||||
* [Precaching with Angular Service Worker](https://web.dev/precaching-with-the-angular-service-worker/)
|
|
||||||
* [Creating a PWA with Angular CLI](https://web.dev/creating-pwa-with-angular-cli/)
|
|
||||||
|
|
||||||
## Next steps
|
|
||||||
|
|
||||||
To begin using Angular service workers, see [Getting Started with service workers](guide/service-worker-getting-started).
|
|
@ -1,84 +1,84 @@
|
|||||||
# Introducción al Service Worker de Angular
|
# Angular service worker introduction
|
||||||
|
|
||||||
Los service Workers amplían el modelo de implementación web tradicional y permiten que las aplicaciones brinden una experiencia de usuario con la confiabilidad y el rendimiento a la par del código instalado de forma nativa. Agregar un service worker a una aplicación Angular es uno de los pasos para convertir una aplicación en una [Aplicación web progresiva] (https://developers.google.com/web/progressive-web-apps/) (también conocida como PWA ).
|
Service workers augment the traditional web deployment model and empower applications to deliver a user experience with the reliability and performance on par with natively-installed code. Adding a service worker to an Angular application is one of the steps for turning an application into a [Progressive Web App](https://developers.google.com/web/progressive-web-apps/) (also known as a PWA).
|
||||||
|
|
||||||
En su forma más simple, un service worker es un script que se ejecuta en el navegador web y administra el almacenamiento en caché de una aplicación.
|
At its simplest, a service worker is a script that runs in the web browser and manages caching for an application.
|
||||||
|
|
||||||
Los service workers funcionan como un proxy de red. Interceptan todas las solicitudes HTTP salientes realizadas por la aplicación y pueden elegir cómo responderlas. Por ejemplo, pueden consultar un caché local y entregar una respuesta en caché si hay una disponible. El proxy no se limita a las solicitudes realizadas a través de código para consumir API, como "fetch"; también incluye recursos referenciados en HTML e incluso la solicitud inicial a `index.html`. El almacenamiento en caché basado en service workers es, por lo tanto, completamente programable y no depende de los encabezados de almacenamiento en caché especificados por el servidor.
|
Service workers function as a network proxy. They intercept all outgoing HTTP requests made by the application and can choose how to respond to them. For example, they can query a local cache and deliver a cached response if one is available. Proxying isn't limited to requests made through programmatic APIs, such as `fetch`; it also includes resources referenced in HTML and even the initial request to `index.html`. Service worker-based caching is thus completely programmable and doesn't rely on server-specified caching headers.
|
||||||
|
|
||||||
A diferencia de los otros scripts que componen una aplicación, como el paquete de la aplicación Angular, el service worker se conserva después de que el usuario cierre la pestaña. La próxima vez que el navegador cargue la aplicación, el service worker cargará primero y podrá interceptar cada solicitud de recursos para cargar la aplicación. Si el service worker está diseñado para hacerlo, puede *satisfacer completamente la carga de la aplicación, sin necesidad de la red*.
|
Unlike the other scripts that make up an application, such as the Angular app bundle, the service worker is preserved after the user closes the tab. The next time that browser loads the application, the service worker loads first, and can intercept every request for resources to load the application. If the service worker is designed to do so, it can *completely satisfy the loading of the application, without the need for the network*.
|
||||||
|
|
||||||
Incluso en una red rápida y fiable, los retrasos de ida y vuelta pueden introducir una latencia significativa al cargar la aplicación. El uso de un service worker para reducir la dependencia de la red puede mejorar significativamente la experiencia del usuario.
|
Even across a fast reliable network, round-trip delays can introduce significant latency when loading the application. Using a service worker to reduce dependency on the network can significantly improve the user experience.
|
||||||
|
|
||||||
|
|
||||||
## Service workers en Angular
|
## Service workers in Angular
|
||||||
|
|
||||||
Las aplicaciones de Angular, como aplicaciones de una sola página, están en una posición privilegiada para beneficiarse de las ventajas de los service workers. A partir de la versión 5.0.0, Angular se envía con una implementación del service worker. Los desarrolladores de Angular pueden aprovechar este service worker y beneficiarse de la mayor fiabilidad y rendimiento que proporciona, sin necesidad de codificar con APIs de bajo nivel.
|
Angular applications, as single-page applications, are in a prime position to benefit from the advantages of service workers. Starting with version 5.0.0, Angular ships with a service worker implementation. Angular developers can take advantage of this service worker and benefit from the increased reliability and performance it provides, without needing to code against low-level APIs.
|
||||||
|
|
||||||
El service worker de Angular está diseñado para optimizar la experiencia del usuario final al usar una aplicación en una conexión de red lenta o poco fiable, al mismo tiempo que minimiza los riesgos de ofrecer contenido desactualizado.
|
Angular's service worker is designed to optimize the end user experience of using an application over a slow or unreliable network connection, while also minimizing the risks of serving outdated content.
|
||||||
|
|
||||||
El comportamiento del service worker de Angular sigue ese objetivo de diseño:
|
The Angular service worker's behavior follows that design goal:
|
||||||
|
|
||||||
* El almacenamiento en caché de una aplicación es como instalar una aplicación nativa. La aplicación se almacena en caché como una unidad y todos los archivos se actualizan juntos.
|
* Caching an application is like installing a native application. The application is cached as one unit, and all files update together.
|
||||||
* Una aplicación en ejecución continúa ejecutándose con la misma versión de todos los archivos. No comienza a recibir repentinamente archivos en caché de una versión más reciente, que probablemente sean incompatibles.
|
* A running application continues to run with the same version of all files. It does not suddenly start receiving cached files from a newer version, which are likely incompatible.
|
||||||
* Cuando los usuarios actualizan la aplicación, ven la última versión completamente almacenada en caché. Las pestañas nuevas cargan el último código almacenado en caché.
|
* When users refresh the application, they see the latest fully cached version. New tabs load the latest cached code.
|
||||||
* Las actualizaciones ocurren en segundo plano, relativamente rápido después de que se publican los cambios. La versión anterior de la aplicación se sirve hasta que se instala y está lista una actualización.
|
* Updates happen in the background, relatively quickly after changes are published. The previous version of the application is served until an update is installed and ready.
|
||||||
* El service worker conserva el ancho de banda cuando es posible. Los recursos solo se descargan si han cambiado.
|
* The service worker conserves bandwidth when possible. Resources are only downloaded if they've changed.
|
||||||
|
|
||||||
Para admitir estos comportamientos, el service worker de Angular carga un archivo * manifiesto * desde el servidor. El manifiesto describe los recursos para almacenar en caché e incluye hashes del contenido de cada archivo. Cuando se implementa una actualización de la aplicación, el contenido del manifiesto cambia e informa al service worker que se debe descargar y almacenar en caché una nueva versión de la aplicación. Este manifiesto se genera a partir de un archivo de configuración generado por CLI llamado `ngsw-config.json`.
|
To support these behaviors, the Angular service worker loads a *manifest* file from the server. The manifest describes the resources to cache and includes hashes of every file's contents. When an update to the application is deployed, the contents of the manifest change, informing the service worker that a new version of the application should be downloaded and cached. This manifest is generated from a CLI-generated configuration file called `ngsw-config.json`.
|
||||||
|
|
||||||
Instalar el service worker de Angular es tan simple como incluir un `NgModule`. Además de registrar el service worker de Angular en el navegador, esto también hace que algunos servicios estén disponibles para inyección que interactúan con el service worker y se pueden usar para controlarlo. Por ejemplo, una aplicación puede solicitar que se le notifique cuando esté disponible una nueva actualización, o una aplicación puede pedirle al service worker que busque actualizaciones disponibles en el servidor.
|
Installing the Angular service worker is as simple as including an `NgModule`. In addition to registering the Angular service worker with the browser, this also makes a few services available for injection which interact with the service worker and can be used to control it. For example, an application can ask to be notified when a new update becomes available, or an application can ask the service worker to check the server for available updates.
|
||||||
|
|
||||||
## Requisitos previos
|
## Prerequisites
|
||||||
|
|
||||||
Para hacer uso de todas las características del Angular service worker, use las últimas versiones de Angular y Angular CLI.
|
To make use of all the features of Angular service worker, use the latest versions of Angular and the Angular CLI.
|
||||||
|
|
||||||
Para que los service workers se registren, se debe acceder a la aplicación a través de HTTPS, no de HTTP.
|
In order for service workers to be registered, the app must be accessed over HTTPS, not HTTP.
|
||||||
Los navegadores ignoran a los service workers en las páginas que se sirven a través de una conexión insegura.
|
Browsers ignore service workers on pages that are served over an insecure connection.
|
||||||
La razón es que los service workers son bastante poderosos, por lo que se debe tener especial cuidado para garantizar que el script del service worker no se haya alterado.
|
The reason is that service workers are quite powerful, so extra care needs to be taken to ensure the service worker script has not been tampered with.
|
||||||
|
|
||||||
Hay una excepción a esta regla: para facilitar el desarrollo local, los navegadores _no_ requieren una conexión segura al acceder a una aplicación en `localhost`.
|
There is one exception to this rule: to make local development easier, browsers do _not_ require a secure connection when accessing an app on `localhost`.
|
||||||
|
|
||||||
### Soporte de navegador
|
### Browser support
|
||||||
|
|
||||||
Para beneficiarse del service worker de Angular, su aplicación debe ejecutarse en un navegador web que admita service workers en general.
|
To benefit from the Angular service worker, your app must run in a web browser that supports service workers in general.
|
||||||
Actualmente, los service workers son compatibles con las últimas versiones de Chrome, Firefox, Edge, Safari, Opera, UC Browser (versión de Android) y Samsung Internet.
|
Currently, service workers are supported in the latest versions of Chrome, Firefox, Edge, Safari, Opera, UC Browser (Android version) and Samsung Internet.
|
||||||
Los navegadores como IE y Opera Mini no son compatibles con los service workers.
|
Browsers like IE and Opera Mini do not support service workers.
|
||||||
|
|
||||||
Si el usuario accede a su aplicación a través de un navegador que no es compatible con los service workers, el service worker no es registrado y el comportamiento relacionado como la administración de caché sin conexión y las notificaciones automáticas, no ocurre.
|
If the user is accessing your app via a browser that does not support service workers, the service worker is not registered and related behavior such as offline cache management and push notifications does not happen.
|
||||||
Más específicamente:
|
More specifically:
|
||||||
|
|
||||||
* El navegador no descarga la secuencia de comandos del service worker y el archivo de manifiesto `ngsw.json`.
|
* The browser does not download the service worker script and `ngsw.json` manifest file.
|
||||||
* Intentos activos de interactuar con el service worker, como llamar a `SwUpdate.checkForUpdate ()`, devuelve promesas rechazadas.
|
* Active attempts to interact with the service worker, such as calling `SwUpdate.checkForUpdate()`, return rejected promises.
|
||||||
* Los eventos observables de servicios relacionados, como "SwUpdate.available", no se activan.
|
* The observable events of related services, such as `SwUpdate.available`, are not triggered.
|
||||||
|
|
||||||
Se recomienda encarecidamente que se asegure de que su aplicación funcione incluso sin la asistencia del trabajador de servicio en el navegador.
|
It is highly recommended that you ensure that your app works even without service worker support in the browser.
|
||||||
Aunque un navegador no compatible ignora el almacenamiento en caché del service worker, seguirá informando errores si la aplicación intenta interactuar con el service worker.
|
Although an unsupported browser ignores service worker caching, it will still report errors if the app attempts to interact with the service worker.
|
||||||
Por ejemplo, llamar a `SwUpdate.checkForUpdate ()` devolverá las promesas rechazadas.
|
For example, calling `SwUpdate.checkForUpdate()` will return rejected promises.
|
||||||
Para evitar tal error, puede verificar si el service worker de Angular está habilitado usando `SwUpdate.isEnabled ()`.
|
To avoid such an error, you can check whether the Angular service worker is enabled using `SwUpdate.isEnabled()`.
|
||||||
|
|
||||||
Para obtener más información sobre otros navegadores que soportan service workers, consulta [Can I Use](https://caniuse.com/#feat=serviceworkers) y [MDN docs](https://developer.mozilla.org/en-US/docs/Web/API/Service_Worker_API).
|
To learn more about other browsers that are service worker ready, see the [Can I Use](https://caniuse.com/#feat=serviceworkers) page and [MDN docs](https://developer.mozilla.org/en-US/docs/Web/API/Service_Worker_API).
|
||||||
|
|
||||||
|
|
||||||
## Recursos Relacionados
|
## Related resources
|
||||||
|
|
||||||
El resto de los artículos de esta sección abordan específicamente la implementación de los service workers en Angular.
|
The rest of the articles in this section specifically address the Angular implementation of service workers.
|
||||||
|
|
||||||
* [App Shell](guide/app-shell)
|
* [App Shell](guide/app-shell)
|
||||||
* [Comunicación del Service Worker](guide/service-worker-communications)
|
* [Service Worker Communication](guide/service-worker-communications)
|
||||||
* [Service Worker en producción](guide/service-worker-devops)
|
* [Service Worker in Production](guide/service-worker-devops)
|
||||||
* [Service Worker Configuración](guide/service-worker-config)
|
* [Service Worker Configuration](guide/service-worker-config)
|
||||||
|
|
||||||
Para obtener más información sobre los service workers en general, consulta [Service Workers: una Introducción](https://developers.google.com/web/fundamentals/primers/service-workers/).
|
For more information about service workers in general, see [Service Workers: an Introduction](https://developers.google.com/web/fundamentals/primers/service-workers/).
|
||||||
|
|
||||||
Para obtener más información sobre la compatibilidad con el navegador, consulta la [soporte del navegador](https://developers.google.com/web/fundamentals/primers/service-workers/#browser_support) sección de [Service Workers: an Introduction](https://developers.google.com/web/fundamentals/primers/service-workers/), [Is Serviceworker ready?](https://jakearchibald.github.io/isserviceworkerready/) Jake Archibald, y
|
For more information about browser support, see the [browser support](https://developers.google.com/web/fundamentals/primers/service-workers/#browser_support) section of [Service Workers: an Introduction](https://developers.google.com/web/fundamentals/primers/service-workers/), Jake Archibald's [Is Serviceworker ready?](https://jakearchibald.github.io/isserviceworkerready/), and
|
||||||
[Can I Use](http://caniuse.com/#feat=serviceworkers).
|
[Can I Use](http://caniuse.com/#feat=serviceworkers).
|
||||||
|
|
||||||
Para obtener recomendaciones y ejemplos adicionales, consulta:
|
For additional recommendations and examples, see:
|
||||||
|
|
||||||
* [Precaching con Angular Service Worker](https://web.dev/precaching-with-the-angular-service-worker/)
|
* [Precaching with Angular Service Worker](https://web.dev/precaching-with-the-angular-service-worker/)
|
||||||
* [Creando una PWA con Angular CLI](https://web.dev/creating-pwa-with-angular-cli/)
|
* [Creating a PWA with Angular CLI](https://web.dev/creating-pwa-with-angular-cli/)
|
||||||
|
|
||||||
## Siguientes pasos con el Angular CLI
|
## Next steps
|
||||||
|
|
||||||
Comienza a usar los service workers en Angular, consulta [Introducción a los trabajadores del servicio](guide/service-worker-getting-started).
|
To begin using Angular service workers, see [Getting Started with service workers](guide/service-worker-getting-started).
|
||||||
|
@ -8,7 +8,7 @@ Incluye información sobre los requisitos previos, la instalación de la CLI, la
|
|||||||
<div class="callout is-helpful">
|
<div class="callout is-helpful">
|
||||||
<header>Prueba Angular sin configuración local</header>
|
<header>Prueba Angular sin configuración local</header>
|
||||||
|
|
||||||
Si eres nuevo en Angular, quizás quieras comenzar con [¡Pruébalo ahora!](start), que presenta los aspectos esenciales de Angular en el contexto de una aplicación de tienda en línea básica lista para usar que puedes examinar y modificar. Este tutorial independiente aprovecha lo interactivo del ambiente [StackBlitz](https://stackblitz.com/) para el desarrollo online. No es necesario que configures tu entorno local hasta que estés listo.
|
Si eres nuevo en Angular, quizás quieras comenzar con [¡Pruebalo ahora!](start), que presenta los aspectos esenciales de Angular en el contexto de una aplicación de tienda en línea básica lista para usar que puedes examinar y modificar. Este tutorial independiente aprovecha lo interactivo del ambiente [StackBlitz](https://stackblitz.com/) para el desarrollo online. No es necesario que configures tu entorno local hasta que estes listo.
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@ -25,7 +25,7 @@ Para usar el framewok Angular, debes estar familiarizado con lo siguiente:
|
|||||||
|
|
||||||
Conocimiento de [TypeScript](https://www.typescriptlang.org/) es útil, pero no obligatorio.
|
Conocimiento de [TypeScript](https://www.typescriptlang.org/) es útil, pero no obligatorio.
|
||||||
|
|
||||||
Para instalar Angular en tu sistema local, necesitas lo siguiente:
|
Para instalar Angular en su sistema local, necesitas lo siguiente:
|
||||||
|
|
||||||
{@a nodejs}
|
{@a nodejs}
|
||||||
|
|
||||||
@ -40,7 +40,7 @@ Para instalar Angular en tu sistema local, necesitas lo siguiente:
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
Para obtener más información sobre la instalación de Node.js, consulta [nodejs.org](http://nodejs.org "Nodejs.org").
|
Para obtener más información sobre la instalación de Node.js, consulta [nodejs.org](http://nodejs.org "Nodejs.org").
|
||||||
Si no estás seguro de qué versión de Node.js se ejecuta en tu sistema, ejecuta `node -v` en una terminal.
|
Si no estas seguro de qué versión de Node.js se ejecuta en tu sistema, ejecuta `node -v` en una terminal.
|
||||||
|
|
||||||
{@a npm}
|
{@a npm}
|
||||||
|
|
||||||
@ -49,14 +49,14 @@ Para instalar Angular en tu sistema local, necesitas lo siguiente:
|
|||||||
Angular, CLI de Angular, y las aplicaciones de Angular dependen de [paquetes npm](https://docs.npmjs.com/getting-started/what-is-npm) para muchas funcionalidades y funciones.
|
Angular, CLI de Angular, y las aplicaciones de Angular dependen de [paquetes npm](https://docs.npmjs.com/getting-started/what-is-npm) para muchas funcionalidades y funciones.
|
||||||
Para descargar e instalar paquetes npm, necesitas un administrador de paquetes npm.
|
Para descargar e instalar paquetes npm, necesitas un administrador de paquetes npm.
|
||||||
Esta guía utiliza la interfaz de línea de comandos del [cliente npm](https://docs.npmjs.com/cli/install), que se instala con `Node.js` por defecto.
|
Esta guía utiliza la interfaz de línea de comandos del [cliente npm](https://docs.npmjs.com/cli/install), que se instala con `Node.js` por defecto.
|
||||||
Para comprobar que tienes instalado el cliente npm, ejecuta `npm -v` en una terminal.
|
Para comprobar que tiene instalado el cliente npm, ejecute `npm -v` en una terminal.
|
||||||
|
|
||||||
|
|
||||||
{@a install-cli}
|
{@a install-cli}
|
||||||
|
|
||||||
## Instalar la CLI de Angular
|
## Instalar la CLI de Angular
|
||||||
|
|
||||||
Utilizarás la CLI de Angular para crear proyectos, generar código de aplicaciones y bibliotecas, y realizar una variedad de tareas de desarrollo, como pruebas, agrupación e implementación.
|
Utilizaraz la CLI de Angular para crear proyectos, generar código de aplicaciones y bibliotecas, y realizar una variedad de tareas de desarrollo, como pruebas, agrupación e implementación.
|
||||||
|
|
||||||
Para instalar CLI de Angular, abre una terminal y ejecuta el siguiente comando:
|
Para instalar CLI de Angular, abre una terminal y ejecuta el siguiente comando:
|
||||||
|
|
||||||
@ -79,7 +79,7 @@ Para crear un nuevo espacio de trabajo y una aplicación inicial:
|
|||||||
|
|
||||||
</code-example>
|
</code-example>
|
||||||
|
|
||||||
2. El comando `ng new` te solicitará información sobre las funciones que debe incluir en la aplicación inicial. Acepta los valores predeterminados presionando la tecla Enter o Return.
|
2. El comando `ng new` te solicitara información sobre las funciones que debe incluir en la aplicación inicial. Acepta los valores predeterminados presionando la tecla Enter o Return.
|
||||||
|
|
||||||
La CLI de Angular instala los paquetes npm de Angular necesarios y otras dependencias. Esto puede tardar unos minutos.
|
La CLI de Angular instala los paquetes npm de Angular necesarios y otras dependencias. Esto puede tardar unos minutos.
|
||||||
|
|
||||||
@ -87,7 +87,7 @@ La CLI crea un nuevo espacio de trabajo y una aplicación de bienvenida simple,
|
|||||||
|
|
||||||
<div class="alert is-helpful">
|
<div class="alert is-helpful">
|
||||||
|
|
||||||
También tienes la opción de usar el modo estricto de Angular, que puede ayudarte a escribir un mejor código y más fácil de mantener.
|
También tienes la opción de usar el modo estricto de Angular, que puede ayudarte a escribir un código mejor y más fácil de mantener.
|
||||||
Para más información, mira [Modo estricto](/guide/strict-mode).
|
Para más información, mira [Modo estricto](/guide/strict-mode).
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
@ -107,10 +107,10 @@ La CLI de Angular incluye un servidor, de modo que puede crear y servir su aplic
|
|||||||
ng serve --open
|
ng serve --open
|
||||||
</code-example>
|
</code-example>
|
||||||
|
|
||||||
El comando `ng serve` inicia el servidor, observa tus archivos,
|
El comando `ng serve` inicia el servidor, observa sus archivos,
|
||||||
y reconstruye la aplicación a medida que realizas cambios en esos archivos.
|
y reconstruye la aplicación a medida que realizas cambios en esos archivos.
|
||||||
|
|
||||||
La opción `--open` (o simplemente` -o`) abre automáticamente tu navegador
|
La opción `--open` (o simplemente` -o`) abre automáticamente su navegador
|
||||||
en `http://localhost:4200/`.
|
en `http://localhost:4200/`.
|
||||||
|
|
||||||
Si tu instalación y configuración fue exitosa, deberías ver una página similar a la siguiente.
|
Si tu instalación y configuración fue exitosa, deberías ver una página similar a la siguiente.
|
||||||
@ -125,7 +125,7 @@ Si tu instalación y configuración fue exitosa, deberías ver una página simil
|
|||||||
|
|
||||||
* Para obtener una introducción más completa a los conceptos fundamentales y la terminología de la arquitectura de aplicaciones de una sola página y los principios de diseño de Angular, lee la sección [Conceptos Angular](guide/architecture) .
|
* Para obtener una introducción más completa a los conceptos fundamentales y la terminología de la arquitectura de aplicaciones de una sola página y los principios de diseño de Angular, lee la sección [Conceptos Angular](guide/architecture) .
|
||||||
|
|
||||||
* Trabaja en el [Tutorial de Tour de los Héroes](tutorial), un ejercicio práctico completo que te presenta el proceso de desarrollo de aplicaciones mediante la CLI de Angular y te explica los subsistemas importantes.
|
* Trabaja en el [Tutorial de Tour de los Heroes](tutorial), un ejercicio práctico completo que te presenta el proceso de desarrollo de aplicaciones mediante la CLI de Angular y te explica los subsistemas importantes.
|
||||||
|
|
||||||
* Para obtener más información sobre el uso de la CLI de Angular, consulta la [Descripción general del CLI](cli "CLI Overview"). Además de crear el espacio de trabajo inicial y andamios de la aplicación, puedes usar la CLI para generar código de Angular como componentes y servicios. La CLI soporta el ciclo de desarrollo completo, incluida la creación, las pruebas, la agrupación y la implementación.
|
* Para obtener más información sobre el uso de la CLI de Angular, consulta la [Descripción general del CLI](cli "CLI Overview"). Además de crear el espacio de trabajo inicial y andamios de la aplicación, puedes usar la CLI para generar código de Angular como componentes y servicios. La CLI soporta el ciclo de desarrollo completo, incluida la creación, las pruebas, la agrupación y la implementación.
|
||||||
|
|
||||||
|
@ -1,62 +0,0 @@
|
|||||||
# Sharing modules
|
|
||||||
|
|
||||||
Creating shared modules allows you to organize and streamline your code. You can put commonly
|
|
||||||
used directives, pipes, and components into one module and then import just that module wherever
|
|
||||||
you need it in other parts of your app.
|
|
||||||
|
|
||||||
Consider the following module from an imaginary app:
|
|
||||||
|
|
||||||
|
|
||||||
```typescript
|
|
||||||
import { CommonModule } from '@angular/common';
|
|
||||||
import { NgModule } from '@angular/core';
|
|
||||||
import { FormsModule } from '@angular/forms';
|
|
||||||
import { CustomerComponent } from './customer.component';
|
|
||||||
import { NewItemDirective } from './new-item.directive';
|
|
||||||
import { OrdersPipe } from './orders.pipe';
|
|
||||||
|
|
||||||
@NgModule({
|
|
||||||
imports: [ CommonModule ],
|
|
||||||
declarations: [ CustomerComponent, NewItemDirective, OrdersPipe ],
|
|
||||||
exports: [ CustomerComponent, NewItemDirective, OrdersPipe,
|
|
||||||
CommonModule, FormsModule ]
|
|
||||||
})
|
|
||||||
export class SharedModule { }
|
|
||||||
```
|
|
||||||
|
|
||||||
Note the following:
|
|
||||||
|
|
||||||
* It imports the `CommonModule` because the module's component needs common directives.
|
|
||||||
* It declares and exports the utility pipe, directive, and component classes.
|
|
||||||
* It re-exports the `CommonModule` and `FormsModule`.
|
|
||||||
|
|
||||||
By re-exporting `CommonModule` and `FormsModule`, any other module that imports this
|
|
||||||
`SharedModule`, gets access to directives like `NgIf` and `NgFor` from `CommonModule`
|
|
||||||
and can bind to component properties with `[(ngModel)]`, a directive in the `FormsModule`.
|
|
||||||
|
|
||||||
Even though the components declared by `SharedModule` might not bind
|
|
||||||
with `[(ngModel)]` and there may be no need for `SharedModule`
|
|
||||||
to import `FormsModule`, `SharedModule` can still export
|
|
||||||
`FormsModule` without listing it among its `imports`. This
|
|
||||||
way, you can give other modules access to `FormsModule` without
|
|
||||||
having to import it directly into the `@NgModule` decorator.
|
|
||||||
|
|
||||||
### Using components vs services from other modules
|
|
||||||
|
|
||||||
There is an important distinction between using another module's component and
|
|
||||||
using a service from another module. Import modules when you want to use
|
|
||||||
directives, pipes, and components. Importing a module with services means that you will have a new instance of that service, which typically is not what you need (typically one wants to reuse an existing service). Use module imports to control service instantiation.
|
|
||||||
|
|
||||||
The most common way to get a hold of shared services is through Angular
|
|
||||||
[dependency injection](guide/dependency-injection), rather than through the module system (importing a module will result in a new service instance, which is not a typical usage).
|
|
||||||
|
|
||||||
To read about sharing services, see [Providers](guide/providers).
|
|
||||||
|
|
||||||
|
|
||||||
<hr />
|
|
||||||
|
|
||||||
## More on NgModules
|
|
||||||
|
|
||||||
You may also be interested in the following:
|
|
||||||
* [Providers](guide/providers).
|
|
||||||
* [Types of Feature Modules](guide/module-types).
|
|
@ -1,8 +1,10 @@
|
|||||||
# Compartiendo módulos
|
# Sharing modules
|
||||||
|
|
||||||
La creación de módulos compartidos te permite organizar y optimizar tu código. Puedes colocar directivas, `pipes`, y componentes de uso común en un módulo y despues importar solo ese módulo donde lo necesites en otras partes de tu aplicación.
|
Creating shared modules allows you to organize and streamline your code. You can put commonly
|
||||||
|
used directives, pipes, and components into one module and then import just that module wherever
|
||||||
|
you need it in other parts of your app.
|
||||||
|
|
||||||
Considera el siguiente módulo de una aplicación imaginaria:
|
Consider the following module from an imaginary app:
|
||||||
|
|
||||||
|
|
||||||
```typescript
|
```typescript
|
||||||
@ -22,33 +24,39 @@ import { OrdersPipe } from './orders.pipe';
|
|||||||
export class SharedModule { }
|
export class SharedModule { }
|
||||||
```
|
```
|
||||||
|
|
||||||
Ten en cuenta lo siguiente:
|
Note the following:
|
||||||
|
|
||||||
* Esto importa `CommonModule` porque el componente del módulo necesita directivas comunes.
|
* It imports the `CommonModule` because the module's component needs common directives.
|
||||||
* Declara y exporta las clases de componentes, directivas y `pipes`
|
* It declares and exports the utility pipe, directive, and component classes.
|
||||||
* Esto reexporta `CommonModule` y `FormsModule`.
|
* It re-exports the `CommonModule` and `FormsModule`.
|
||||||
|
|
||||||
Al reexportar `CommonModule` y `FormsModule`, cualquier otro módulo que importe este
|
By re-exporting `CommonModule` and `FormsModule`, any other module that imports this
|
||||||
`SharedModule`, obtiene acceso a directivas como `NgIf` y `NgFor` desde `CommonModule`
|
`SharedModule`, gets access to directives like `NgIf` and `NgFor` from `CommonModule`
|
||||||
y puede vincularse a las propiedades del componente con `[(ngModel)]`, a una directiva en `FormsModule`.
|
and can bind to component properties with `[(ngModel)]`, a directive in the `FormsModule`.
|
||||||
|
|
||||||
Aunque los componentes declarados por `SharedModule` pueden no vincularse con `[(ngModel)]` y puede que no sea necesario que `SharedModule` importe `FormsModule`, `SharedModule` aún puede exportar
|
Even though the components declared by `SharedModule` might not bind
|
||||||
`FormsModule` sin incluirlo entre sus `imports (importaciones)`. De esta manera, puedes dar acceso a otros módulos a `FormsModule` sin tener que importarlo directamente al decorador `@NgModule`.
|
with `[(ngModel)]` and there may be no need for `SharedModule`
|
||||||
|
to import `FormsModule`, `SharedModule` can still export
|
||||||
|
`FormsModule` without listing it among its `imports`. This
|
||||||
|
way, you can give other modules access to `FormsModule` without
|
||||||
|
having to import it directly into the `@NgModule` decorator.
|
||||||
|
|
||||||
### Uso de componentes vs servicios de otros módulos
|
### Using components vs services from other modules
|
||||||
|
|
||||||
Existe una distinción importante entre usar el componente de otro módulo y utilizar un servicio de otro módulo. Importa módulos cuando quieras usar directivas, `pipes` y componentes. Importar un módulo con servicios significa que tendrá una nueva instancia de ese servicio, que normalmente no es lo que necesitas (normalmente, quieres reutilizar un servicio existente). Utiliza las importaciones de módulos para controlar la creación de instancias de servicios.
|
There is an important distinction between using another module's component and
|
||||||
|
using a service from another module. Import modules when you want to use
|
||||||
|
directives, pipes, and components. Importing a module with services means that you will have a new instance of that service, which typically is not what you need (typically one wants to reuse an existing service). Use module imports to control service instantiation.
|
||||||
|
|
||||||
La forma más común de obtener servicios compartidos es através de la
|
The most common way to get a hold of shared services is through Angular
|
||||||
[inyección de dependencia](guide/dependency-injection) en Angular, en lugar de a través del sistema del módulo (la importación de un módulo dará como resultado una nueva instancia de servicio, que no es un uso típico).
|
[dependency injection](guide/dependency-injection), rather than through the module system (importing a module will result in a new service instance, which is not a typical usage).
|
||||||
|
|
||||||
Para leer acerca de compartir servicios, consulta [Proveedores](guide/providers).
|
To read about sharing services, see [Providers](guide/providers).
|
||||||
|
|
||||||
|
|
||||||
<hr />
|
<hr />
|
||||||
|
|
||||||
## Más en NgModules
|
## More on NgModules
|
||||||
|
|
||||||
También te puede interesar lo siguiente:
|
You may also be interested in the following:
|
||||||
* [Proveedores](guide/providers).
|
* [Providers](guide/providers).
|
||||||
* [Tipos de Módulos de funciones](guide/module-types).
|
* [Types of Feature Modules](guide/module-types).
|
||||||
|
@ -18,12 +18,7 @@ Una declaración de plantilla *tiene un efecto secundario*.
|
|||||||
Ese es el objetivo de un evento.
|
Ese es el objetivo de un evento.
|
||||||
Es la forma de actualizar el estado de la aplicación a partir de la acción del usuario.
|
Es la forma de actualizar el estado de la aplicación a partir de la acción del usuario.
|
||||||
|
|
||||||
|
Responder a los eventos es el otro lado del "flujo de datos unidireccional" de Angular.
|
||||||
<div class="alert is-helpful">
|
|
||||||
|
|
||||||
Responder a los eventos es un aspecto del [flujo de datos unidireccional](guide/glossary#unidirectional-data-flow) de Angular.
|
|
||||||
|
|
||||||
</div>
|
|
||||||
Eres libre de cambiar cualquier cosa, en cualquier lugar, durante este ciclo del evento.
|
Eres libre de cambiar cualquier cosa, en cualquier lugar, durante este ciclo del evento.
|
||||||
|
|
||||||
Al igual que las expresiones de plantilla, las *declaraciones* de plantilla utilizan un lenguaje que se parece a JavaScript.
|
Al igual que las expresiones de plantilla, las *declaraciones* de plantilla utilizan un lenguaje que se parece a JavaScript.
|
||||||
|
@ -1,73 +0,0 @@
|
|||||||
# Template syntax
|
|
||||||
|
|
||||||
In Angular, a *template* is a chunk of HTML.
|
|
||||||
Within a template, you can use special syntax to leverage many of Angular's features.
|
|
||||||
|
|
||||||
|
|
||||||
## Prerequisites
|
|
||||||
|
|
||||||
Before learning template syntax, you should be familiar with the following:
|
|
||||||
|
|
||||||
* [Angular concepts](guide/architecture)
|
|
||||||
* JavaScript
|
|
||||||
* HTML
|
|
||||||
* CSS
|
|
||||||
|
|
||||||
|
|
||||||
<!-- Do we still need the following section? It seems more relevant to those coming from AngularJS, which is now 7 versions ago. -->
|
|
||||||
<!-- You may be familiar with the component/template duality from your experience with model-view-controller (MVC) or model-view-viewmodel (MVVM).
|
|
||||||
In Angular, the component plays the part of the controller/viewmodel, and the template represents the view. -->
|
|
||||||
|
|
||||||
<hr />
|
|
||||||
|
|
||||||
Each Angular template in your app is a section of HTML that you can include as a part of the page that the browser displays.
|
|
||||||
An Angular HTML template renders a view, or user interface, in the browser, just like regular HTML, but with a lot more functionality.
|
|
||||||
|
|
||||||
When you generate an Angular app with the Angular CLI, the `app.component.html` file is the default template containing placeholder HTML.
|
|
||||||
|
|
||||||
The template syntax guides show you how you can control the UX/UI by coordinating data between the class and the template.
|
|
||||||
|
|
||||||
<div class="is-helpful alert">
|
|
||||||
|
|
||||||
Most of the Template Syntax guides have dedicated working example apps that demonstrate the individual topic of each guide.
|
|
||||||
To see all of them working together in one app, see the comprehensive <live-example title="Template Syntax Live Code"></live-example>.
|
|
||||||
|
|
||||||
</div>
|
|
||||||
|
|
||||||
|
|
||||||
## Empower your HTML
|
|
||||||
|
|
||||||
With special Angular syntax in your templates, you can extend the HTML vocabulary of your apps.
|
|
||||||
For example, Angular helps you get and set DOM (Document Object Model) values dynamically with features such as built-in template functions, variables, event listening, and data binding.
|
|
||||||
|
|
||||||
Almost all HTML syntax is valid template syntax.
|
|
||||||
However, because an Angular template is part of an overall webpage, and not the entire page, you don't need to include elements such as `<html>`, `<body>`, or `<base>`.
|
|
||||||
You can focus exclusively on the part of the page you are developing.
|
|
||||||
|
|
||||||
|
|
||||||
<div class="alert is-important">
|
|
||||||
|
|
||||||
To eliminate the risk of script injection attacks, Angular does not support the `<script>` element in templates.
|
|
||||||
Angular ignores the `<script>` tag and outputs a warning to the browser console.
|
|
||||||
For more information, see the [Security](guide/security) page.
|
|
||||||
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<hr />
|
|
||||||
|
|
||||||
## More on template syntax
|
|
||||||
|
|
||||||
You may also be interested in the following:
|
|
||||||
|
|
||||||
* [Interpolation](guide/interpolation)—learn how to use interpolation and expressions in HTML.
|
|
||||||
* [Template statements](guide/template-statements)—respond to events in your templates.
|
|
||||||
* [Binding syntax](guide/binding-syntax)—use binding to coordinate values in your app.
|
|
||||||
* [Property binding](guide/property-binding)—set properties of target elements or directive `@Input()` decorators.
|
|
||||||
* [Attribute, class, and style bindings](guide/attribute-binding)—set the value of attributes, classes, and styles.
|
|
||||||
* [Event binding](guide/event-binding)—listen for events and your HTML.
|
|
||||||
* [Two-way binding](guide/two-way-binding)—share data between a class and its template.
|
|
||||||
* [Built-in directives](guide/built-in-directives)—listen to and modify the behavior and layout of HTML.
|
|
||||||
* [Template reference variables](guide/template-reference-variables)—use special variables to reference a DOM element within a template.
|
|
||||||
* [Inputs and Outputs](guide/inputs-outputs)—share data between the parent context and child directives or components
|
|
||||||
* [Template expression operators](guide/template-expression-operators)—learn about the pipe operator, `|`, and protect against `null` or `undefined` values in your HTML.
|
|
||||||
* [SVG in templates](guide/svg-in-templates)—dynamically generate interactive graphics.
|
|
@ -1,14 +1,14 @@
|
|||||||
# Sintaxis de la plantilla
|
# Template syntax
|
||||||
|
|
||||||
En Angular, una *plantilla* es un fragmento de HTML.
|
In Angular, a *template* is a chunk of HTML.
|
||||||
Dentro de una plantilla, puedes usar una sintaxis especial para aprovechar muchas de las características de Angular.
|
Within a template, you can use special syntax to leverage many of Angular's features.
|
||||||
|
|
||||||
|
|
||||||
## Prerrequisitos
|
## Prerequisites
|
||||||
|
|
||||||
Antes de aprender la sintaxis de la plantilla, debes estar familiarizado con lo siguiente:
|
Before learning template syntax, you should be familiar with the following:
|
||||||
|
|
||||||
* [Conceptos de Angular](guide/architecture)
|
* [Angular concepts](guide/architecture)
|
||||||
* JavaScript
|
* JavaScript
|
||||||
* HTML
|
* HTML
|
||||||
* CSS
|
* CSS
|
||||||
@ -20,55 +20,54 @@ In Angular, the component plays the part of the controller/viewmodel, and the te
|
|||||||
|
|
||||||
<hr />
|
<hr />
|
||||||
|
|
||||||
Cada plantilla Angular de tu aplicación es una sección de HTML que puedes incluir como parte de la página que muestra el navegador.
|
Each Angular template in your app is a section of HTML that you can include as a part of the page that the browser displays.
|
||||||
Una plantilla HTML Angular muestra una vista, o interfaz de usuario, en el navegador, como HTML normal, pero con mucha más funcionalidad.
|
An Angular HTML template renders a view, or user interface, in the browser, just like regular HTML, but with a lot more functionality.
|
||||||
|
|
||||||
Cuando generas una aplicación Angular con Angular CLI, el archivo `app.component.html` es la plantilla predeterminada que contiene HTML de marcador de posición.
|
When you generate an Angular app with the Angular CLI, the `app.component.html` file is the default template containing placeholder HTML.
|
||||||
|
|
||||||
Las guías de sintaxis de la plantilla te muestran cómo puedes controlar la UX/UI coordinando los datos entre la clase y la plantilla.
|
|
||||||
|
|
||||||
|
The template syntax guides show you how you can control the UX/UI by coordinating data between the class and the template.
|
||||||
|
|
||||||
<div class="is-helpful alert">
|
<div class="is-helpful alert">
|
||||||
|
|
||||||
La mayoría de las guías de sintaxis de plantillas tienen aplicaciones de ejemplo de trabajo dedicadas que demuestran el tema individual de cada guía.
|
Most of the Template Syntax guides have dedicated working example apps that demonstrate the individual topic of each guide.
|
||||||
Para verlos a todos trabajando juntos en una aplicación, consulta al completo<live-example title="Template Syntax Live Code"></live-example>.
|
To see all of them working together in one app, see the comprehensive <live-example title="Template Syntax Live Code"></live-example>.
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
||||||
## Potencia tu HTML
|
## Empower your HTML
|
||||||
|
|
||||||
Con una sintaxis Angular especial en tus plantillas, puedes ampliar el vocabulario HTML de tus aplicaciones.
|
With special Angular syntax in your templates, you can extend the HTML vocabulary of your apps.
|
||||||
Por ejemplo, Angular te ayuda a obtener y establecer valores DOM (Document Object Model) dinámicamente con características como funciones de plantilla integradas, variables, escucha de eventos y enlace de datos.
|
For example, Angular helps you get and set DOM (Document Object Model) values dynamically with features such as built-in template functions, variables, event listening, and data binding.
|
||||||
|
|
||||||
Casi toda la sintaxis HTML es una sintaxis de plantilla válida.
|
Almost all HTML syntax is valid template syntax.
|
||||||
Sin embargo, debido a que una plantilla Angular es parte de una página web general, y no de toda la página, no es necesario incluir elementos como `<html>`, `<body>` o `<base>`.
|
However, because an Angular template is part of an overall webpage, and not the entire page, you don't need to include elements such as `<html>`, `<body>`, or `<base>`.
|
||||||
Puedes centrarte exclusivamente en la parte de la página que estás desarrollando.
|
You can focus exclusively on the part of the page you are developing.
|
||||||
|
|
||||||
|
|
||||||
<div class="alert is-important">
|
<div class="alert is-important">
|
||||||
|
|
||||||
Para eliminar el riesgo de ataques de inyección de scripts, Angular no admite el elemento `<script>` en las plantillas.
|
To eliminate the risk of script injection attacks, Angular does not support the `<script>` element in templates.
|
||||||
Angular ignora la etiqueta `<script>` y envía una advertencia a la consola del navegador.
|
Angular ignores the `<script>` tag and outputs a warning to the browser console.
|
||||||
Para obtener más información, consulta la página [Seguridad](guide/security).
|
For more information, see the [Security](guide/security) page.
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<hr />
|
<hr />
|
||||||
|
|
||||||
## Más sobre la sintaxis de la plantilla
|
## More on template syntax
|
||||||
|
|
||||||
También te puede interesar lo siguiente:
|
You may also be interested in the following:
|
||||||
|
|
||||||
* [Interpolación](guide/interpolation)—aprende a utilizar la interpolación y las expresiones en HTML.
|
* [Interpolation](guide/interpolation)—learn how to use interpolation and expressions in HTML.
|
||||||
* [Declaraciones de plantilla](guide/template-statements)—responde a eventos en sus plantillas.
|
* [Template statements](guide/template-statements)—respond to events in your templates.
|
||||||
* [Sintaxis de enlace](guide/binding-syntax)—utiliza el enlace para coordinar valores en su aplicación.
|
* [Binding syntax](guide/binding-syntax)—use binding to coordinate values in your app.
|
||||||
* [Vinculación de propiedad](guide/property-binding)—establece las propiedades de los elementos de destino o los decoradores de la directiva `@Input ()`.
|
* [Property binding](guide/property-binding)—set properties of target elements or directive `@Input()` decorators.
|
||||||
* [Vinculaciones de atributos, clases y estilos](guide/attribute-binding)—establece el valor de atributos, clases y estilos.
|
* [Attribute, class, and style bindings](guide/attribute-binding)—set the value of attributes, classes, and styles.
|
||||||
* [Enlace de eventos](guide/event-binding)—escucha los eventos y tu HTML.
|
* [Event binding](guide/event-binding)—listen for events and your HTML.
|
||||||
* [Enlace bidireccional](guide/two-way-binding)—comparte datos entre una clase y su plantilla.
|
* [Two-way binding](guide/two-way-binding)—share data between a class and its template.
|
||||||
* [Directivas integradas](guide/built-in-directives)—escucha y modifica el comportamiento y el diseño del HTML.
|
* [Built-in directives](guide/built-in-directives)—listen to and modify the behavior and layout of HTML.
|
||||||
* [Variables de referencia de plantilla](guide/template-reference-variables)—usa variables especiales para hacer referencia a un elemento DOM dentro de una plantilla.
|
* [Template reference variables](guide/template-reference-variables)—use special variables to reference a DOM element within a template.
|
||||||
* [Entradas y salidas](guide/inputs-outputs)—comparte datos entre el contexto principal y las directivas o componentes secundarios
|
* [Inputs and Outputs](guide/inputs-outputs)—share data between the parent context and child directives or components
|
||||||
* [Operadores de expresión de plantilla](guide/template-expression-operators)—aprende sobre el operador de tubería, `|`, y protégete contra valores `nulos` o` indefinidos` en tu HTML.
|
* [Template expression operators](guide/template-expression-operators)—learn about the pipe operator, `|`, and protect against `null` or `undefined` values in your HTML.
|
||||||
* [SVG en plantillas](guide/svg-in-templates)—genera gráficos interactivos de forma dinámica.
|
* [SVG in templates](guide/svg-in-templates)—dynamically generate interactive graphics.
|
||||||
|
@ -1,29 +0,0 @@
|
|||||||
# Debugging tests
|
|
||||||
|
|
||||||
If your tests aren't working as you expect them to, you can inspect and debug them in the browser.
|
|
||||||
|
|
||||||
<div class="alert is-helpful">
|
|
||||||
|
|
||||||
For the sample app that the testing guides describe, see the <live-example name="testing" embedded-style noDownload>sample app</live-example>.
|
|
||||||
|
|
||||||
For the tests features in the testing guides, see <live-example name="testing" stackblitz="specs" noDownload>tests</live-example>.
|
|
||||||
|
|
||||||
</div>
|
|
||||||
|
|
||||||
|
|
||||||
Debug specs in the browser in the same way that you debug an application.
|
|
||||||
|
|
||||||
1. Reveal the Karma browser window. See [Set up testing](guide/testing#set-up-testing) if you need help with this step.
|
|
||||||
1. Click the **DEBUG** button; it opens a new browser tab and re-runs the tests.
|
|
||||||
1. Open the browser's “Developer Tools” (`Ctrl-Shift-I` on Windows; `Command-Option-I` in macOS).
|
|
||||||
1. Pick the "sources" section.
|
|
||||||
1. Open the `1st.spec.ts` test file (Control/Command-P, then start typing the name of the file).
|
|
||||||
1. Set a breakpoint in the test.
|
|
||||||
1. Refresh the browser, and it stops at the breakpoint.
|
|
||||||
|
|
||||||
<div class="lightbox">
|
|
||||||
<img src='generated/images/guide/testing/karma-1st-spec-debug.png' alt="Karma debugging">
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<hr>
|
|
||||||
|
|
@ -1,29 +1,28 @@
|
|||||||
# Debugging tests
|
# Debugging tests
|
||||||
|
|
||||||
Si tus tests no están funcionando como esperas, puedes inspeccionarlos y hacer debug en el navegador.
|
If your tests aren't working as you expect them to, you can inspect and debug them in the browser.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<div class="alert is-helpful">
|
<div class="alert is-helpful">
|
||||||
Para la aplicación de ejemplo que las guías de testing describe, consulta <live-example name="testing" embedded-style noDownload>app de ejemplo</live-example>.
|
|
||||||
|
|
||||||
Para las funcionalidades de los tests en las guías de testing, consulta <live-example name="testing" stackblitz="specs" noDownload>tests</live-example>.
|
For the sample app that the testing guides describe, see the <live-example name="testing" embedded-style noDownload>sample app</live-example>.
|
||||||
|
|
||||||
|
For the tests features in the testing guides, see <live-example name="testing" stackblitz="specs" noDownload>tests</live-example>.
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
Puedes hacer debug de especificaciones en el navegador de la misma forma que haces debug a una aplicación.
|
|
||||||
|
|
||||||
1. Revela la ventana del navegador Karma. Consulta [configuración del testing](guide/testing#set-up-testing) si necesitas ayuda con este paso.
|
Debug specs in the browser in the same way that you debug an application.
|
||||||
1. Haz click en el botón **DEBUG**; abrirá una nueva pestaña en el navegador y volverá a ejecutar los tests.
|
|
||||||
1. Abre las "Herramientas de desarrollador" del navegador (`Ctrl-Shift-I` en Windows; `Command-Option-I` in macOS).
|
1. Reveal the Karma browser window. See [Set up testing](guide/testing#set-up-testing) if you need help with this step.
|
||||||
1. Selecciona la sección "fuentes".
|
1. Click the **DEBUG** button; it opens a new browser tab and re-runs the tests.
|
||||||
1. Abre el archivo test `1st.spec.ts` (Control/Command-P, luego escribe el nombre del archivo).
|
1. Open the browser's “Developer Tools” (`Ctrl-Shift-I` on Windows; `Command-Option-I` in macOS).
|
||||||
1. Coloca un breakpoint en el test.
|
1. Pick the "sources" section.
|
||||||
1. Actualiza tu navegador, se detendrá en el breakpoint establecido.
|
1. Open the `1st.spec.ts` test file (Control/Command-P, then start typing the name of the file).
|
||||||
|
1. Set a breakpoint in the test.
|
||||||
|
1. Refresh the browser, and it stops at the breakpoint.
|
||||||
|
|
||||||
<div class="lightbox">
|
<div class="lightbox">
|
||||||
<img src='generated/images/guide/testing/karma-1st-spec-debug.png' alt="Karma debugging">
|
<img src='generated/images/guide/testing/karma-1st-spec-debug.png' alt="Karma debugging">
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<hr>
|
<hr>
|
||||||
|
|
||||||
|
@ -1,78 +0,0 @@
|
|||||||
|
|
||||||
{@a attribute-directive}
|
|
||||||
|
|
||||||
# Testing Attribute Directives
|
|
||||||
|
|
||||||
An _attribute directive_ modifies the behavior of an element, component or another directive.
|
|
||||||
Its name reflects the way the directive is applied: as an attribute on a host element.
|
|
||||||
|
|
||||||
<div class="alert is-helpful">
|
|
||||||
|
|
||||||
For the sample app that the testing guides describe, see the <live-example name="testing" embedded-style noDownload>sample app</live-example>.
|
|
||||||
|
|
||||||
For the tests features in the testing guides, see <live-example name="testing" stackblitz="specs" noDownload>tests</live-example>.
|
|
||||||
|
|
||||||
</div>
|
|
||||||
|
|
||||||
## Testing the `HighlightDirective`
|
|
||||||
|
|
||||||
The sample application's `HighlightDirective` sets the background color of an element
|
|
||||||
based on either a data bound color or a default color (lightgray).
|
|
||||||
It also sets a custom property of the element (`customProperty`) to `true`
|
|
||||||
for no reason other than to show that it can.
|
|
||||||
|
|
||||||
<code-example path="testing/src/app/shared/highlight.directive.ts" header="app/shared/highlight.directive.ts"></code-example>
|
|
||||||
|
|
||||||
It's used throughout the application, perhaps most simply in the `AboutComponent`:
|
|
||||||
|
|
||||||
<code-example path="testing/src/app/about/about.component.ts" header="app/about/about.component.ts"></code-example>
|
|
||||||
|
|
||||||
Testing the specific use of the `HighlightDirective` within the `AboutComponent` requires only the techniques explored in the ["Nested component tests"](guide/testing-components-scenarios#nested-component-tests) section of [Component testing scenarios](guide/testing-components-scenarios).
|
|
||||||
|
|
||||||
<code-example path="testing/src/app/about/about.component.spec.ts" region="tests" header="app/about/about.component.spec.ts"></code-example>
|
|
||||||
|
|
||||||
However, testing a single use case is unlikely to explore the full range of a directive's capabilities.
|
|
||||||
Finding and testing all components that use the directive is tedious, brittle, and almost as unlikely to afford full coverage.
|
|
||||||
|
|
||||||
_Class-only tests_ might be helpful,
|
|
||||||
but attribute directives like this one tend to manipulate the DOM.
|
|
||||||
Isolated unit tests don't touch the DOM and, therefore,
|
|
||||||
do not inspire confidence in the directive's efficacy.
|
|
||||||
|
|
||||||
A better solution is to create an artificial test component that demonstrates all ways to apply the directive.
|
|
||||||
|
|
||||||
<code-example path="testing/src/app/shared/highlight.directive.spec.ts" region="test-component" header="app/shared/highlight.directive.spec.ts (TestComponent)"></code-example>
|
|
||||||
|
|
||||||
<div class="lightbox">
|
|
||||||
<img src='generated/images/guide/testing/highlight-directive-spec.png' alt="HighlightDirective spec in action">
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="alert is-helpful">
|
|
||||||
|
|
||||||
The `<input>` case binds the `HighlightDirective` to the name of a color value in the input box.
|
|
||||||
The initial value is the word "cyan" which should be the background color of the input box.
|
|
||||||
|
|
||||||
</div>
|
|
||||||
|
|
||||||
Here are some tests of this component:
|
|
||||||
|
|
||||||
<code-example path="testing/src/app/shared/highlight.directive.spec.ts" region="selected-tests" header="app/shared/highlight.directive.spec.ts (selected tests)"></code-example>
|
|
||||||
|
|
||||||
A few techniques are noteworthy:
|
|
||||||
|
|
||||||
- The `By.directive` predicate is a great way to get the elements that have this directive _when their element types are unknown_.
|
|
||||||
|
|
||||||
- The <a href="https://developer.mozilla.org/en-US/docs/Web/CSS/:not">`:not` pseudo-class</a>
|
|
||||||
in `By.css('h2:not([highlight])')` helps find `<h2>` elements that _do not_ have the directive.
|
|
||||||
`By.css('*:not([highlight])')` finds _any_ element that does not have the directive.
|
|
||||||
|
|
||||||
- `DebugElement.styles` affords access to element styles even in the absence of a real browser, thanks to the `DebugElement` abstraction.
|
|
||||||
But feel free to exploit the `nativeElement` when that seems easier or more clear than the abstraction.
|
|
||||||
|
|
||||||
- Angular adds a directive to the injector of the element to which it is applied.
|
|
||||||
The test for the default color uses the injector of the second `<h2>` to get its `HighlightDirective` instance
|
|
||||||
and its `defaultColor`.
|
|
||||||
|
|
||||||
- `DebugElement.properties` affords access to the artificial custom property that is set by the directive.
|
|
||||||
|
|
||||||
<hr>
|
|
@ -1,44 +1,45 @@
|
|||||||
|
|
||||||
{@a attribute-directive}
|
{@a attribute-directive}
|
||||||
|
|
||||||
# Probando Directivas de Atributo
|
# Testing Attribute Directives
|
||||||
|
|
||||||
Una _directiva de atributo_ modifica el comportamiento de un elemento, componente u otra directiva.
|
An _attribute directive_ modifies the behavior of an element, component or another directive.
|
||||||
Su nombre refleja la forma en que se aplica la directiva: como un atributo en un elemento anfitrión.
|
Its name reflects the way the directive is applied: as an attribute on a host element.
|
||||||
|
|
||||||
<div class="alert is-helpful">
|
<div class="alert is-helpful">
|
||||||
|
|
||||||
Para la aplicación de muestra que describen las guías de prueba, visita la <live-example name="testing" embedded-style noDownload>aplicación de muestra</live-example>.
|
For the sample app that the testing guides describe, see the <live-example name="testing" embedded-style noDownload>sample app</live-example>.
|
||||||
|
|
||||||
Para las funcionalidaddes de las pruebas en las guías de pruebas, visita las <live-example name="testing" stackblitz="specs" noDownload>pruebas</live-example>.
|
For the tests features in the testing guides, see <live-example name="testing" stackblitz="specs" noDownload>tests</live-example>.
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
## Probando la `HighlightDirective`
|
## Testing the `HighlightDirective`
|
||||||
|
|
||||||
La directiva de muestra `HighlightDirective` fija el color de fondo de un elemento basado en un color de referencia o en un color predeterminado (lightgray).
|
The sample application's `HighlightDirective` sets the background color of an element
|
||||||
También establece una propiedad personalizada del elemento (`customProperty`) a `true`
|
based on either a data bound color or a default color (lightgray).
|
||||||
sin otro motivo más que demostrar que puede.
|
It also sets a custom property of the element (`customProperty`) to `true`
|
||||||
|
for no reason other than to show that it can.
|
||||||
|
|
||||||
<code-example path="testing/src/app/shared/highlight.directive.ts" header="app/shared/highlight.directive.ts"></code-example>
|
<code-example path="testing/src/app/shared/highlight.directive.ts" header="app/shared/highlight.directive.ts"></code-example>
|
||||||
|
|
||||||
Se usa a lo largo de la aplicación, quizás más sencillamente en el `AboutComponent`:
|
It's used throughout the application, perhaps most simply in the `AboutComponent`:
|
||||||
|
|
||||||
<code-example path="testing/src/app/about/about.component.ts" header="app/about/about.component.ts"></code-example>
|
<code-example path="testing/src/app/about/about.component.ts" header="app/about/about.component.ts"></code-example>
|
||||||
|
|
||||||
Probar el uso específico de la `HighlightDirective` dentro del `AboutComponent` sólo requiere las técnicas exploradas en la sección ["Pruebas de componentes anidados"](guide/testing-components-scenarios#nested-component-tests) de [Escenarios de pruebas de componentes](guide/testing-components-scenarios).
|
Testing the specific use of the `HighlightDirective` within the `AboutComponent` requires only the techniques explored in the ["Nested component tests"](guide/testing-components-scenarios#nested-component-tests) section of [Component testing scenarios](guide/testing-components-scenarios).
|
||||||
|
|
||||||
<code-example path="testing/src/app/about/about.component.spec.ts" region="tests" header="app/about/about.component.spec.ts"></code-example>
|
<code-example path="testing/src/app/about/about.component.spec.ts" region="tests" header="app/about/about.component.spec.ts"></code-example>
|
||||||
|
|
||||||
Sin embargo, probar un solo caso de uso es poco probable que explore toda la variedad de las posibilidades de una directiva.
|
However, testing a single use case is unlikely to explore the full range of a directive's capabilities.
|
||||||
Encontrar y probar todos los componentes que utilizan la directiva es tedioso, delicado y casi igual de improbable que permita una cobertura completa.
|
Finding and testing all components that use the directive is tedious, brittle, and almost as unlikely to afford full coverage.
|
||||||
|
|
||||||
Las _Pruebas de clase exclusivas_ pueden ser de ayuda,
|
_Class-only tests_ might be helpful,
|
||||||
pero las directivas de atributo como ésta tienden a manipular el DOM.
|
but attribute directives like this one tend to manipulate the DOM.
|
||||||
Las pruebas unitarias aisladas no tocan el DOM y, por lo tanto,
|
Isolated unit tests don't touch the DOM and, therefore,
|
||||||
no inspiran confianza en la eficacia de la directiva.
|
do not inspire confidence in the directive's efficacy.
|
||||||
|
|
||||||
Una solución mejor es crear un componente de prueba artificial que demuestre todas las formas de aplicar la directiva.
|
A better solution is to create an artificial test component that demonstrates all ways to apply the directive.
|
||||||
|
|
||||||
<code-example path="testing/src/app/shared/highlight.directive.spec.ts" region="test-component" header="app/shared/highlight.directive.spec.ts (TestComponent)"></code-example>
|
<code-example path="testing/src/app/shared/highlight.directive.spec.ts" region="test-component" header="app/shared/highlight.directive.spec.ts (TestComponent)"></code-example>
|
||||||
|
|
||||||
@ -48,30 +49,30 @@ Una solución mejor es crear un componente de prueba artificial que demuestre to
|
|||||||
|
|
||||||
<div class="alert is-helpful">
|
<div class="alert is-helpful">
|
||||||
|
|
||||||
El caso de `<input>` vincula la `HighlightDirective` al nombre de un valor de color en el campo de entrada.
|
The `<input>` case binds the `HighlightDirective` to the name of a color value in the input box.
|
||||||
El valor inicial es la palabra "cyan" que debería ser el color de fondo del cuadro de entrada.
|
The initial value is the word "cyan" which should be the background color of the input box.
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
Aquí hay algunas pruebas de este componente:
|
Here are some tests of this component:
|
||||||
|
|
||||||
<code-example path="testing/src/app/shared/highlight.directive.spec.ts" region="selected-tests" header="app/shared/highlight.directive.spec.ts (selected tests)"></code-example>
|
<code-example path="testing/src/app/shared/highlight.directive.spec.ts" region="selected-tests" header="app/shared/highlight.directive.spec.ts (selected tests)"></code-example>
|
||||||
|
|
||||||
Cabe destacar algunas técnicas:
|
A few techniques are noteworthy:
|
||||||
|
|
||||||
- El predicado de la `By.directive` es una buena forma de obtener los elementos que tienen esta directiva _cuando sus tipos de elementos son desconocidos_.
|
- The `By.directive` predicate is a great way to get the elements that have this directive _when their element types are unknown_.
|
||||||
|
|
||||||
- La <a href="https://developer.mozilla.org/en-US/docs/Web/CSS/:not">`:not` pseudo-clase</a>
|
- The <a href="https://developer.mozilla.org/en-US/docs/Web/CSS/:not">`:not` pseudo-class</a>
|
||||||
en `By.css('h2:not([highlight])')` ayuda a encontrar los elementos `<h2>` _que no_ tienen la directiva.
|
in `By.css('h2:not([highlight])')` helps find `<h2>` elements that _do not_ have the directive.
|
||||||
`By.css('*:not([highlight])')` encuentra _cualquier_ elemento que no tiene la directiva.
|
`By.css('*:not([highlight])')` finds _any_ element that does not have the directive.
|
||||||
|
|
||||||
- `DebugElement.styles` permite acceder a los estilos de los elementos incluso en ausencia de un navegador real, gracias a la abstracción de `DebugElement`.
|
- `DebugElement.styles` affords access to element styles even in the absence of a real browser, thanks to the `DebugElement` abstraction.
|
||||||
Pero siéntete libre de explotar el `nativeElement` cuando te parezca más fácil o más claro que la abstracción.
|
But feel free to exploit the `nativeElement` when that seems easier or more clear than the abstraction.
|
||||||
|
|
||||||
- Angular añade una directiva al inyector del elemento al que se aplica.
|
- Angular adds a directive to the injector of the element to which it is applied.
|
||||||
La prueba para el color por defecto usa el inyector del segundo `<h2>` para obtener la instancia de su `HighlightDirective`
|
The test for the default color uses the injector of the second `<h2>` to get its `HighlightDirective` instance
|
||||||
y su `defaultColor`.
|
and its `defaultColor`.
|
||||||
|
|
||||||
- `DebugElement.properties` permite el acceso a la propiedad artificial personalizada que se establece en la directiva.
|
- `DebugElement.properties` affords access to the artificial custom property that is set by the directive.
|
||||||
|
|
||||||
<hr>
|
<hr>
|
||||||
|
@ -1,57 +0,0 @@
|
|||||||
{@a code-coverage}
|
|
||||||
|
|
||||||
# Find out how much code you're testing
|
|
||||||
|
|
||||||
The CLI can run unit tests and create code coverage reports.
|
|
||||||
Code coverage reports show you any parts of your code base that may not be properly tested by your unit tests.
|
|
||||||
|
|
||||||
<div class="alert is-helpful">
|
|
||||||
|
|
||||||
For the sample app that the testing guides describe, see the <live-example name="testing" embedded-style noDownload>sample app</live-example>.
|
|
||||||
|
|
||||||
For the tests features in the testing guides, see <live-example name="testing" stackblitz="specs" noDownload>tests</live-example>.
|
|
||||||
|
|
||||||
</div>
|
|
||||||
|
|
||||||
|
|
||||||
To generate a coverage report run the following command in the root of your project.
|
|
||||||
|
|
||||||
<code-example language="sh" class="code-shell">
|
|
||||||
ng test --no-watch --code-coverage
|
|
||||||
</code-example>
|
|
||||||
|
|
||||||
When the tests are complete, the command creates a new `/coverage` folder in the project. Open the `index.html` file to see a report with your source code and code coverage values.
|
|
||||||
|
|
||||||
If you want to create code-coverage reports every time you test, you can set the following option in the CLI configuration file, `angular.json`:
|
|
||||||
|
|
||||||
```
|
|
||||||
"test": {
|
|
||||||
"options": {
|
|
||||||
"codeCoverage": true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
## Code coverage enforcement
|
|
||||||
|
|
||||||
The code coverage percentages let you estimate how much of your code is tested.
|
|
||||||
If your team decides on a set minimum amount to be unit tested, you can enforce this minimum with the Angular CLI.
|
|
||||||
|
|
||||||
For example, suppose you want the code base to have a minimum of 80% code coverage.
|
|
||||||
To enable this, open the [Karma](https://karma-runner.github.io) test platform configuration file, `karma.conf.js`, and add the following in the `coverageIstanbulReporter:` key.
|
|
||||||
|
|
||||||
```
|
|
||||||
coverageIstanbulReporter: {
|
|
||||||
reports: [ 'html', 'lcovonly' ],
|
|
||||||
fixWebpackSourcePaths: true,
|
|
||||||
thresholds: {
|
|
||||||
statements: 80,
|
|
||||||
lines: 80,
|
|
||||||
branches: 80,
|
|
||||||
functions: 80
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
The `thresholds` property causes the tool to enforce a minimum of 80% code coverage when the unit tests are run in the project.
|
|
||||||
|
|
@ -1,28 +1,28 @@
|
|||||||
{@a code-coverage}
|
{@a code-coverage}
|
||||||
|
|
||||||
# Descubre cuánto código estás probando
|
# Find out how much code you're testing
|
||||||
|
|
||||||
El CLI puede ejecutar tests unitarios y crear informes de la cobertura del codigo por ellos.
|
The CLI can run unit tests and create code coverage reports.
|
||||||
Los informes de cobertura de código muestran las partes de tu código que pueden no estar siento probadas corretamente por sus test unitarios.
|
Code coverage reports show you any parts of your code base that may not be properly tested by your unit tests.
|
||||||
|
|
||||||
<div class="alert is-helpful">
|
<div class="alert is-helpful">
|
||||||
|
|
||||||
Para la aplicación de muestra que describen las guías de prueba, visita la <live-example name="testing" embedded-style noDownload>aplicación de muestra</live-example>.
|
For the sample app that the testing guides describe, see the <live-example name="testing" embedded-style noDownload>sample app</live-example>.
|
||||||
|
|
||||||
Para las características de las pruebas en las guías de pruebas, visita <live-example name="testing" stackblitz="specs" noDownload>pruebas</live-example>.
|
For the tests features in the testing guides, see <live-example name="testing" stackblitz="specs" noDownload>tests</live-example>.
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
||||||
Para generar un informe de cobertura ejecuta el siguiente comando en la raíz del proyecto.
|
To generate a coverage report run the following command in the root of your project.
|
||||||
|
|
||||||
<code-example language="sh" class="code-shell">
|
<code-example language="sh" class="code-shell">
|
||||||
ng test --no-watch --code-coverage
|
ng test --no-watch --code-coverage
|
||||||
</code-example>
|
</code-example>
|
||||||
|
|
||||||
Cuando las pruebas terminan, el comando crea una nueva carpeta `/coverage` en el proyecto. Abre el archivo `index.html` para ver un informe con tu código y los valores de cobertura de código.
|
When the tests are complete, the command creates a new `/coverage` folder in the project. Open the `index.html` file to see a report with your source code and code coverage values.
|
||||||
|
|
||||||
Si quieres crear informes de cobertura de código cada vez que ejecutes los test, puedes configurar la siguiente opción en el archivo de configuración del CLI, `angular.json`:
|
If you want to create code-coverage reports every time you test, you can set the following option in the CLI configuration file, `angular.json`:
|
||||||
|
|
||||||
```
|
```
|
||||||
"test": {
|
"test": {
|
||||||
@ -32,13 +32,13 @@ Si quieres crear informes de cobertura de código cada vez que ejecutes los test
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
## Imponer la cobertura de código
|
## Code coverage enforcement
|
||||||
|
|
||||||
Los porcentajes de cobertura de código te permiten estimar cuánto porcentaje de tu código es probado.
|
The code coverage percentages let you estimate how much of your code is tested.
|
||||||
Si tu equipo decide fijar una cantidad mínima de código para ser probada unitariamente puedes imponer este mínimo con el CLI de Angular.
|
If your team decides on a set minimum amount to be unit tested, you can enforce this minimum with the Angular CLI.
|
||||||
|
|
||||||
Por ejemplo, supongamos que quieres que el código tenga un mínimo de 80% de cobertura de código.
|
For example, suppose you want the code base to have a minimum of 80% code coverage.
|
||||||
Para habilitarlo, abre el archivo de configuración de la plataforma de pruebas de [Karma](https://karma-runner.github.io), `karma.conf.js`, y añada lo siguiente en la clave `coverageIstanbulReporter:`.
|
To enable this, open the [Karma](https://karma-runner.github.io) test platform configuration file, `karma.conf.js`, and add the following in the `coverageIstanbulReporter:` key.
|
||||||
|
|
||||||
```
|
```
|
||||||
coverageIstanbulReporter: {
|
coverageIstanbulReporter: {
|
||||||
@ -53,5 +53,5 @@ coverageIstanbulReporter: {
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
La propiedad de los `thresholds` hace que la herramienta aplique un mínimo del 80% de cobertura de código cuando se ejecuten las pruebas unitarias en el proyecto.
|
The `thresholds` property causes the tool to enforce a minimum of 80% code coverage when the unit tests are run in the project.
|
||||||
|
|
||||||
|
@ -1,794 +0,0 @@
|
|||||||
# Testing Utility APIs
|
|
||||||
|
|
||||||
This page describes the most useful Angular testing features.
|
|
||||||
|
|
||||||
The Angular testing utilities include the `TestBed`, the `ComponentFixture`, and a handful of functions that control the test environment.
|
|
||||||
The [_TestBed_](#testbed-api-summary) and [_ComponentFixture_](#component-fixture-api-summary) classes are covered separately.
|
|
||||||
|
|
||||||
Here's a summary of the stand-alone functions, in order of likely utility:
|
|
||||||
|
|
||||||
<table>
|
|
||||||
<tr>
|
|
||||||
<th>
|
|
||||||
Function
|
|
||||||
</th>
|
|
||||||
<th>
|
|
||||||
Description
|
|
||||||
</th>
|
|
||||||
</tr>
|
|
||||||
|
|
||||||
<tr>
|
|
||||||
<td style="vertical-align: top">
|
|
||||||
<code>async</code>
|
|
||||||
</td>
|
|
||||||
|
|
||||||
<td>
|
|
||||||
|
|
||||||
Runs the body of a test (`it`) or setup (`beforeEach`) function within a special _async test zone_.
|
|
||||||
See [discussion above](guide/testing-components-scenarios#waitForAsync).
|
|
||||||
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
|
|
||||||
<tr>
|
|
||||||
<td style="vertical-align: top">
|
|
||||||
<code>fakeAsync</code>
|
|
||||||
</td>
|
|
||||||
|
|
||||||
<td>
|
|
||||||
|
|
||||||
Runs the body of a test (`it`) within a special _fakeAsync test zone_, enabling
|
|
||||||
a linear control flow coding style. See [discussion above](guide/testing-components-scenarios#fake-async).
|
|
||||||
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
|
|
||||||
<tr>
|
|
||||||
<td style="vertical-align: top">
|
|
||||||
<code>tick</code>
|
|
||||||
</td>
|
|
||||||
|
|
||||||
<td>
|
|
||||||
|
|
||||||
Simulates the passage of time and the completion of pending asynchronous activities
|
|
||||||
by flushing both _timer_ and _micro-task_ queues within the _fakeAsync test zone_.
|
|
||||||
|
|
||||||
<div class="alert is-helpful">
|
|
||||||
|
|
||||||
The curious, dedicated reader might enjoy this lengthy blog post,
|
|
||||||
["_Tasks, microtasks, queues and schedules_"](https://jakearchibald.com/2015/tasks-microtasks-queues-and-schedules/).
|
|
||||||
|
|
||||||
</div>
|
|
||||||
|
|
||||||
Accepts an optional argument that moves the virtual clock forward
|
|
||||||
by the specified number of milliseconds,
|
|
||||||
clearing asynchronous activities scheduled within that timeframe.
|
|
||||||
See [discussion above](guide/testing-components-scenarios#tick).
|
|
||||||
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
|
|
||||||
<tr>
|
|
||||||
<td style="vertical-align: top">
|
|
||||||
<code>inject</code>
|
|
||||||
</td>
|
|
||||||
|
|
||||||
<td>
|
|
||||||
|
|
||||||
Injects one or more services from the current `TestBed` injector into a test function.
|
|
||||||
It cannot inject a service provided by the component itself.
|
|
||||||
See discussion of the [debugElement.injector](guide/testing-components-scenarios#get-injected-services).
|
|
||||||
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
|
|
||||||
<tr>
|
|
||||||
<td style="vertical-align: top">
|
|
||||||
<code>discardPeriodicTasks</code>
|
|
||||||
</td>
|
|
||||||
|
|
||||||
<td>
|
|
||||||
|
|
||||||
When a `fakeAsync()` test ends with pending timer event _tasks_ (queued `setTimeOut` and `setInterval` callbacks),
|
|
||||||
the test fails with a clear error message.
|
|
||||||
|
|
||||||
In general, a test should end with no queued tasks.
|
|
||||||
When pending timer tasks are expected, call `discardPeriodicTasks` to flush the _task_ queue
|
|
||||||
and avoid the error.
|
|
||||||
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
|
|
||||||
<tr>
|
|
||||||
<td style="vertical-align: top">
|
|
||||||
<code>flushMicrotasks</code>
|
|
||||||
</td>
|
|
||||||
|
|
||||||
<td>
|
|
||||||
|
|
||||||
When a `fakeAsync()` test ends with pending _micro-tasks_ such as unresolved promises,
|
|
||||||
the test fails with a clear error message.
|
|
||||||
|
|
||||||
In general, a test should wait for micro-tasks to finish.
|
|
||||||
When pending microtasks are expected, call `flushMicrotasks` to flush the _micro-task_ queue
|
|
||||||
and avoid the error.
|
|
||||||
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
|
|
||||||
<tr>
|
|
||||||
<td style="vertical-align: top">
|
|
||||||
<code>ComponentFixtureAutoDetect</code>
|
|
||||||
</td>
|
|
||||||
|
|
||||||
<td>
|
|
||||||
|
|
||||||
A provider token for a service that turns on [automatic change detection](guide/testing-components-scenarios#automatic-change-detection).
|
|
||||||
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
|
|
||||||
<tr>
|
|
||||||
<td style="vertical-align: top">
|
|
||||||
<code>getTestBed</code>
|
|
||||||
</td>
|
|
||||||
|
|
||||||
<td>
|
|
||||||
|
|
||||||
Gets the current instance of the `TestBed`.
|
|
||||||
Usually unnecessary because the static class methods of the `TestBed` class are typically sufficient.
|
|
||||||
The `TestBed` instance exposes a few rarely used members that are not available as
|
|
||||||
static methods.
|
|
||||||
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
</table>
|
|
||||||
|
|
||||||
<hr>
|
|
||||||
|
|
||||||
{@a testbed-class-summary}
|
|
||||||
|
|
||||||
## _TestBed_ class summary
|
|
||||||
|
|
||||||
The `TestBed` class is one of the principal Angular testing utilities.
|
|
||||||
Its API is quite large and can be overwhelming until you've explored it,
|
|
||||||
a little at a time. Read the early part of this guide first
|
|
||||||
to get the basics before trying to absorb the full API.
|
|
||||||
|
|
||||||
The module definition passed to `configureTestingModule`
|
|
||||||
is a subset of the `@NgModule` metadata properties.
|
|
||||||
|
|
||||||
<code-example language="javascript">
|
|
||||||
type TestModuleMetadata = {
|
|
||||||
providers?: any[];
|
|
||||||
declarations?: any[];
|
|
||||||
imports?: any[];
|
|
||||||
schemas?: Array<SchemaMetadata | any[]>;
|
|
||||||
};
|
|
||||||
</code-example>
|
|
||||||
|
|
||||||
{@a metadata-override-object}
|
|
||||||
|
|
||||||
Each override method takes a `MetadataOverride<T>` where `T` is the kind of metadata
|
|
||||||
appropriate to the method, that is, the parameter of an `@NgModule`,
|
|
||||||
`@Component`, `@Directive`, or `@Pipe`.
|
|
||||||
|
|
||||||
<code-example language="javascript">
|
|
||||||
type MetadataOverride<T> = {
|
|
||||||
add?: Partial<T>;
|
|
||||||
remove?: Partial<T>;
|
|
||||||
set?: Partial<T>;
|
|
||||||
};
|
|
||||||
</code-example>
|
|
||||||
|
|
||||||
{@a testbed-methods}
|
|
||||||
{@a testbed-api-summary}
|
|
||||||
|
|
||||||
The `TestBed` API consists of static class methods that either update or reference a _global_ instance of the `TestBed`.
|
|
||||||
|
|
||||||
Internally, all static methods cover methods of the current runtime `TestBed` instance,
|
|
||||||
which is also returned by the `getTestBed()` function.
|
|
||||||
|
|
||||||
Call `TestBed` methods _within_ a `beforeEach()` to ensure a fresh start before each individual test.
|
|
||||||
|
|
||||||
Here are the most important static methods, in order of likely utility.
|
|
||||||
|
|
||||||
<table>
|
|
||||||
<tr>
|
|
||||||
<th>
|
|
||||||
Methods
|
|
||||||
</th>
|
|
||||||
<th>
|
|
||||||
Description
|
|
||||||
</th>
|
|
||||||
</tr>
|
|
||||||
|
|
||||||
<tr>
|
|
||||||
<td style="vertical-align: top">
|
|
||||||
<code>configureTestingModule</code>
|
|
||||||
</td>
|
|
||||||
|
|
||||||
<td>
|
|
||||||
|
|
||||||
The testing shims (`karma-test-shim`, `browser-test-shim`)
|
|
||||||
establish the [initial test environment](guide/testing) and a default testing module.
|
|
||||||
The default testing module is configured with basic declaratives and some Angular service substitutes that every tester needs.
|
|
||||||
|
|
||||||
Call `configureTestingModule` to refine the testing module configuration for a particular set of tests
|
|
||||||
by adding and removing imports, declarations (of components, directives, and pipes), and providers.
|
|
||||||
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
|
|
||||||
<tr>
|
|
||||||
<td style="vertical-align: top">
|
|
||||||
<code>compileComponents</code>
|
|
||||||
</td>
|
|
||||||
|
|
||||||
<td>
|
|
||||||
|
|
||||||
Compile the testing module asynchronously after you've finished configuring it.
|
|
||||||
You **must** call this method if _any_ of the testing module components have a `templateUrl`
|
|
||||||
or `styleUrls` because fetching component template and style files is necessarily asynchronous.
|
|
||||||
See [above](guide/testing-components-scenarios#compile-components).
|
|
||||||
|
|
||||||
After calling `compileComponents`, the `TestBed` configuration is frozen for the duration of the current spec.
|
|
||||||
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
|
|
||||||
<tr>
|
|
||||||
<td style="vertical-align: top">
|
|
||||||
<code>createComponent<T></code>
|
|
||||||
</td>
|
|
||||||
|
|
||||||
<td>
|
|
||||||
|
|
||||||
Create an instance of a component of type `T` based on the current `TestBed` configuration.
|
|
||||||
After calling `compileComponent`, the `TestBed` configuration is frozen for the duration of the current spec.
|
|
||||||
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
|
|
||||||
<tr>
|
|
||||||
<td style="vertical-align: top">
|
|
||||||
<code>overrideModule</code>
|
|
||||||
</td>
|
|
||||||
<td>
|
|
||||||
|
|
||||||
Replace metadata for the given `NgModule`. Recall that modules can import other modules.
|
|
||||||
The `overrideModule` method can reach deeply into the current testing module to
|
|
||||||
modify one of these inner modules.
|
|
||||||
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
|
|
||||||
<tr>
|
|
||||||
<td style="vertical-align: top">
|
|
||||||
<code>overrideComponent</code>
|
|
||||||
</td>
|
|
||||||
|
|
||||||
<td>
|
|
||||||
|
|
||||||
Replace metadata for the given component class, which could be nested deeply
|
|
||||||
within an inner module.
|
|
||||||
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
|
|
||||||
<tr>
|
|
||||||
<td style="vertical-align: top">
|
|
||||||
<code>overrideDirective</code>
|
|
||||||
</td>
|
|
||||||
|
|
||||||
<td>
|
|
||||||
|
|
||||||
Replace metadata for the given directive class, which could be nested deeply
|
|
||||||
within an inner module.
|
|
||||||
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
|
|
||||||
<tr>
|
|
||||||
<td style="vertical-align: top">
|
|
||||||
<code>overridePipe</code>
|
|
||||||
</td>
|
|
||||||
<td>
|
|
||||||
|
|
||||||
Replace metadata for the given pipe class, which could be nested deeply
|
|
||||||
within an inner module.
|
|
||||||
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
|
|
||||||
<tr>
|
|
||||||
<td style="vertical-align: top">
|
|
||||||
{@a testbed-inject}
|
|
||||||
<code>inject</code>
|
|
||||||
</td>
|
|
||||||
|
|
||||||
<td>
|
|
||||||
|
|
||||||
Retrieve a service from the current `TestBed` injector.
|
|
||||||
|
|
||||||
The `inject` function is often adequate for this purpose.
|
|
||||||
But `inject` throws an error if it can't provide the service.
|
|
||||||
|
|
||||||
What if the service is optional?
|
|
||||||
|
|
||||||
The `TestBed.inject()` method takes an optional second parameter,
|
|
||||||
the object to return if Angular can't find the provider
|
|
||||||
(`null` in this example):
|
|
||||||
|
|
||||||
<code-example path="testing/src/app/demo/demo.testbed.spec.ts" region="testbed-get-w-null" header="app/demo/demo.testbed.spec.ts"></code-example>
|
|
||||||
|
|
||||||
After calling `TestBed.inject`, the `TestBed` configuration is frozen for the duration of the current spec.
|
|
||||||
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
|
|
||||||
<tr>
|
|
||||||
<td style="vertical-align: top">
|
|
||||||
{@a testbed-initTestEnvironment}
|
|
||||||
<code>initTestEnvironment</code>
|
|
||||||
</td>
|
|
||||||
<td>
|
|
||||||
|
|
||||||
Initialize the testing environment for the entire test run.
|
|
||||||
|
|
||||||
The testing shims (`karma-test-shim`, `browser-test-shim`) call it for you
|
|
||||||
so there is rarely a reason for you to call it yourself.
|
|
||||||
|
|
||||||
You may call this method _exactly once_. If you must change
|
|
||||||
this default in the middle of your test run, call `resetTestEnvironment` first.
|
|
||||||
|
|
||||||
Specify the Angular compiler factory, a `PlatformRef`, and a default Angular testing module.
|
|
||||||
Alternatives for non-browser platforms are available in the general form
|
|
||||||
`@angular/platform-<platform_name>/testing/<platform_name>`.
|
|
||||||
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
|
|
||||||
<tr>
|
|
||||||
<td style="vertical-align: top">
|
|
||||||
<code>resetTestEnvironment</code>
|
|
||||||
</td>
|
|
||||||
<td>
|
|
||||||
|
|
||||||
Reset the initial test environment, including the default testing module.
|
|
||||||
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
</table>
|
|
||||||
|
|
||||||
A few of the `TestBed` instance methods are not covered by static `TestBed` _class_ methods.
|
|
||||||
These are rarely needed.
|
|
||||||
|
|
||||||
{@a component-fixture-api-summary}
|
|
||||||
|
|
||||||
## The _ComponentFixture_
|
|
||||||
|
|
||||||
The `TestBed.createComponent<T>`
|
|
||||||
creates an instance of the component `T`
|
|
||||||
and returns a strongly typed `ComponentFixture` for that component.
|
|
||||||
|
|
||||||
The `ComponentFixture` properties and methods provide access to the component,
|
|
||||||
its DOM representation, and aspects of its Angular environment.
|
|
||||||
|
|
||||||
{@a component-fixture-properties}
|
|
||||||
|
|
||||||
### _ComponentFixture_ properties
|
|
||||||
|
|
||||||
Here are the most important properties for testers, in order of likely utility.
|
|
||||||
|
|
||||||
<table>
|
|
||||||
<tr>
|
|
||||||
<th>
|
|
||||||
Properties
|
|
||||||
</th>
|
|
||||||
<th>
|
|
||||||
Description
|
|
||||||
</th>
|
|
||||||
</tr>
|
|
||||||
|
|
||||||
<tr>
|
|
||||||
<td style="vertical-align: top">
|
|
||||||
<code>componentInstance</code>
|
|
||||||
</td>
|
|
||||||
|
|
||||||
<td>
|
|
||||||
|
|
||||||
The instance of the component class created by `TestBed.createComponent`.
|
|
||||||
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
|
|
||||||
<tr>
|
|
||||||
<td style="vertical-align: top">
|
|
||||||
<code>debugElement</code>
|
|
||||||
</td>
|
|
||||||
|
|
||||||
<td>
|
|
||||||
|
|
||||||
The `DebugElement` associated with the root element of the component.
|
|
||||||
|
|
||||||
The `debugElement` provides insight into the component and its DOM element during test and debugging.
|
|
||||||
It's a critical property for testers. The most interesting members are covered [below](#debug-element-details).
|
|
||||||
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
|
|
||||||
<tr>
|
|
||||||
<td style="vertical-align: top">
|
|
||||||
<code>nativeElement</code>
|
|
||||||
</td>
|
|
||||||
|
|
||||||
<td>
|
|
||||||
|
|
||||||
The native DOM element at the root of the component.
|
|
||||||
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
|
|
||||||
<tr>
|
|
||||||
<td style="vertical-align: top">
|
|
||||||
<code>changeDetectorRef</code>
|
|
||||||
</td>
|
|
||||||
|
|
||||||
<td>
|
|
||||||
|
|
||||||
The `ChangeDetectorRef` for the component.
|
|
||||||
|
|
||||||
The `ChangeDetectorRef` is most valuable when testing a
|
|
||||||
component that has the `ChangeDetectionStrategy.OnPush` method
|
|
||||||
or the component's change detection is under your programmatic control.
|
|
||||||
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
</table>
|
|
||||||
|
|
||||||
{@a component-fixture-methods}
|
|
||||||
|
|
||||||
### _ComponentFixture_ methods
|
|
||||||
|
|
||||||
The _fixture_ methods cause Angular to perform certain tasks on the component tree.
|
|
||||||
Call these method to trigger Angular behavior in response to simulated user action.
|
|
||||||
|
|
||||||
Here are the most useful methods for testers.
|
|
||||||
|
|
||||||
<table>
|
|
||||||
<tr>
|
|
||||||
<th>
|
|
||||||
Methods
|
|
||||||
</th>
|
|
||||||
<th>
|
|
||||||
Description
|
|
||||||
</th>
|
|
||||||
</tr>
|
|
||||||
|
|
||||||
<tr>
|
|
||||||
<td style="vertical-align: top">
|
|
||||||
<code>detectChanges</code>
|
|
||||||
</td>
|
|
||||||
|
|
||||||
<td>
|
|
||||||
|
|
||||||
Trigger a change detection cycle for the component.
|
|
||||||
|
|
||||||
Call it to initialize the component (it calls `ngOnInit`) and after your
|
|
||||||
test code, change the component's data bound property values.
|
|
||||||
Angular can't see that you've changed `personComponent.name` and won't update the `name`
|
|
||||||
binding until you call `detectChanges`.
|
|
||||||
|
|
||||||
Runs `checkNoChanges` afterwards to confirm that there are no circular updates unless
|
|
||||||
called as `detectChanges(false)`;
|
|
||||||
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
|
|
||||||
<tr>
|
|
||||||
<td style="vertical-align: top">
|
|
||||||
<code>autoDetectChanges</code>
|
|
||||||
</td>
|
|
||||||
|
|
||||||
<td>
|
|
||||||
|
|
||||||
Set this to `true` when you want the fixture to detect changes automatically.
|
|
||||||
|
|
||||||
When autodetect is `true`, the test fixture calls `detectChanges` immediately
|
|
||||||
after creating the component. Then it listens for pertinent zone events
|
|
||||||
and calls `detectChanges` accordingly.
|
|
||||||
When your test code modifies component property values directly,
|
|
||||||
you probably still have to call `fixture.detectChanges` to trigger data binding updates.
|
|
||||||
|
|
||||||
The default is `false`. Testers who prefer fine control over test behavior
|
|
||||||
tend to keep it `false`.
|
|
||||||
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
|
|
||||||
<tr>
|
|
||||||
<td style="vertical-align: top">
|
|
||||||
<code>checkNoChanges</code>
|
|
||||||
</td>
|
|
||||||
|
|
||||||
<td>
|
|
||||||
|
|
||||||
Do a change detection run to make sure there are no pending changes.
|
|
||||||
Throws an exceptions if there are.
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
|
|
||||||
<tr>
|
|
||||||
<td style="vertical-align: top">
|
|
||||||
<code>isStable</code>
|
|
||||||
</td>
|
|
||||||
|
|
||||||
<td>
|
|
||||||
|
|
||||||
If the fixture is currently _stable_, returns `true`.
|
|
||||||
If there are async tasks that have not completed, returns `false`.
|
|
||||||
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
|
|
||||||
<tr>
|
|
||||||
<td style="vertical-align: top">
|
|
||||||
<code>whenStable</code>
|
|
||||||
</td>
|
|
||||||
|
|
||||||
<td>
|
|
||||||
|
|
||||||
Returns a promise that resolves when the fixture is stable.
|
|
||||||
|
|
||||||
To resume testing after completion of asynchronous activity or
|
|
||||||
asynchronous change detection, hook that promise.
|
|
||||||
See [above](guide/testing-components-scenarios#when-stable).
|
|
||||||
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
|
|
||||||
<tr>
|
|
||||||
<td style="vertical-align: top">
|
|
||||||
<code>destroy</code>
|
|
||||||
</td>
|
|
||||||
|
|
||||||
<td>
|
|
||||||
|
|
||||||
Trigger component destruction.
|
|
||||||
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
</table>
|
|
||||||
|
|
||||||
{@a debug-element-details}
|
|
||||||
|
|
||||||
#### _DebugElement_
|
|
||||||
|
|
||||||
The `DebugElement` provides crucial insights into the component's DOM representation.
|
|
||||||
|
|
||||||
From the test root component's `DebugElement` returned by `fixture.debugElement`,
|
|
||||||
you can walk (and query) the fixture's entire element and component subtrees.
|
|
||||||
|
|
||||||
Here are the most useful `DebugElement` members for testers, in approximate order of utility:
|
|
||||||
|
|
||||||
<table>
|
|
||||||
<tr>
|
|
||||||
<th>
|
|
||||||
Member
|
|
||||||
</th>
|
|
||||||
<th>
|
|
||||||
Description
|
|
||||||
</th>
|
|
||||||
</tr>
|
|
||||||
|
|
||||||
<tr>
|
|
||||||
<td style="vertical-align: top">
|
|
||||||
<code>nativeElement</code>
|
|
||||||
</td>
|
|
||||||
|
|
||||||
<td>
|
|
||||||
|
|
||||||
The corresponding DOM element in the browser (null for WebWorkers).
|
|
||||||
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
|
|
||||||
<tr>
|
|
||||||
<td style="vertical-align: top">
|
|
||||||
<code>query</code>
|
|
||||||
</td>
|
|
||||||
|
|
||||||
<td>
|
|
||||||
|
|
||||||
Calling `query(predicate: Predicate<DebugElement>)` returns the first `DebugElement`
|
|
||||||
that matches the [predicate](#query-predicate) at any depth in the subtree.
|
|
||||||
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
|
|
||||||
<tr>
|
|
||||||
<td style="vertical-align: top">
|
|
||||||
<code>queryAll</code>
|
|
||||||
</td>
|
|
||||||
|
|
||||||
<td>
|
|
||||||
|
|
||||||
Calling `queryAll(predicate: Predicate<DebugElement>)` returns all `DebugElements`
|
|
||||||
that matches the [predicate](#query-predicate) at any depth in subtree.
|
|
||||||
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
|
|
||||||
<tr>
|
|
||||||
<td style="vertical-align: top">
|
|
||||||
<code>injector</code>
|
|
||||||
</td>
|
|
||||||
|
|
||||||
<td>
|
|
||||||
|
|
||||||
The host dependency injector.
|
|
||||||
For example, the root element's component instance injector.
|
|
||||||
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
|
|
||||||
<tr>
|
|
||||||
<td style="vertical-align: top">
|
|
||||||
<code>componentInstance</code>
|
|
||||||
</td>
|
|
||||||
|
|
||||||
<td>
|
|
||||||
|
|
||||||
The element's own component instance, if it has one.
|
|
||||||
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
|
|
||||||
<tr>
|
|
||||||
<td style="vertical-align: top">
|
|
||||||
<code>context</code>
|
|
||||||
</td>
|
|
||||||
|
|
||||||
<td>
|
|
||||||
|
|
||||||
An object that provides parent context for this element.
|
|
||||||
Often an ancestor component instance that governs this element.
|
|
||||||
|
|
||||||
When an element is repeated within `*ngFor`, the context is an `NgForRow` whose `$implicit`
|
|
||||||
property is the value of the row instance value.
|
|
||||||
For example, the `hero` in `*ngFor="let hero of heroes"`.
|
|
||||||
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
|
|
||||||
<tr>
|
|
||||||
<td style="vertical-align: top">
|
|
||||||
<code>children</code>
|
|
||||||
</td>
|
|
||||||
|
|
||||||
<td>
|
|
||||||
|
|
||||||
The immediate `DebugElement` children. Walk the tree by descending through `children`.
|
|
||||||
|
|
||||||
<div class="alert is-helpful">
|
|
||||||
|
|
||||||
`DebugElement` also has `childNodes`, a list of `DebugNode` objects.
|
|
||||||
`DebugElement` derives from `DebugNode` objects and there are often
|
|
||||||
more nodes than elements. Testers can usually ignore plain nodes.
|
|
||||||
|
|
||||||
</div>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
|
|
||||||
<tr>
|
|
||||||
<td style="vertical-align: top">
|
|
||||||
<code>parent</code>
|
|
||||||
</td>
|
|
||||||
<td>
|
|
||||||
|
|
||||||
The `DebugElement` parent. Null if this is the root element.
|
|
||||||
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
|
|
||||||
<tr>
|
|
||||||
<td style="vertical-align: top">
|
|
||||||
<code>name</code>
|
|
||||||
</td>
|
|
||||||
|
|
||||||
<td>
|
|
||||||
|
|
||||||
The element tag name, if it is an element.
|
|
||||||
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
|
|
||||||
<tr>
|
|
||||||
<td style="vertical-align: top">
|
|
||||||
<code>triggerEventHandler</code>
|
|
||||||
</td>
|
|
||||||
<td>
|
|
||||||
|
|
||||||
Triggers the event by its name if there is a corresponding listener
|
|
||||||
in the element's `listeners` collection.
|
|
||||||
The second parameter is the _event object_ expected by the handler.
|
|
||||||
See [above](guide/testing-components-scenarios#trigger-event-handler).
|
|
||||||
|
|
||||||
If the event lacks a listener or there's some other problem,
|
|
||||||
consider calling `nativeElement.dispatchEvent(eventObject)`.
|
|
||||||
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
|
|
||||||
<tr>
|
|
||||||
<td style="vertical-align: top">
|
|
||||||
<code>listeners</code>
|
|
||||||
</td>
|
|
||||||
|
|
||||||
<td>
|
|
||||||
|
|
||||||
The callbacks attached to the component's `@Output` properties and/or the element's event properties.
|
|
||||||
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
|
|
||||||
<tr>
|
|
||||||
<td style="vertical-align: top">
|
|
||||||
<code>providerTokens</code>
|
|
||||||
</td>
|
|
||||||
|
|
||||||
<td>
|
|
||||||
|
|
||||||
This component's injector lookup tokens.
|
|
||||||
Includes the component itself plus the tokens that the component lists in its `providers` metadata.
|
|
||||||
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
|
|
||||||
<tr>
|
|
||||||
<td style="vertical-align: top">
|
|
||||||
<code>source</code>
|
|
||||||
</td>
|
|
||||||
|
|
||||||
<td>
|
|
||||||
|
|
||||||
Where to find this element in the source component template.
|
|
||||||
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
|
|
||||||
<tr>
|
|
||||||
<td style="vertical-align: top">
|
|
||||||
<code>references</code>
|
|
||||||
</td>
|
|
||||||
|
|
||||||
<td>
|
|
||||||
|
|
||||||
Dictionary of objects associated with template local variables (e.g. `#foo`),
|
|
||||||
keyed by the local variable name.
|
|
||||||
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
</table>
|
|
||||||
|
|
||||||
{@a query-predicate}
|
|
||||||
|
|
||||||
The `DebugElement.query(predicate)` and `DebugElement.queryAll(predicate)` methods take a
|
|
||||||
predicate that filters the source element's subtree for matching `DebugElement`.
|
|
||||||
|
|
||||||
The predicate is any method that takes a `DebugElement` and returns a _truthy_ value.
|
|
||||||
The following example finds all `DebugElements` with a reference to a template local variable named "content":
|
|
||||||
|
|
||||||
<code-example path="testing/src/app/demo/demo.testbed.spec.ts" region="custom-predicate" header="app/demo/demo.testbed.spec.ts"></code-example>
|
|
||||||
|
|
||||||
The Angular `By` class has three static methods for common predicates:
|
|
||||||
|
|
||||||
- `By.all` - return all elements.
|
|
||||||
- `By.css(selector)` - return elements with matching CSS selectors.
|
|
||||||
- `By.directive(directive)` - return elements that Angular matched to an instance of the directive class.
|
|
||||||
|
|
||||||
<code-example path="testing/src/app/hero/hero-list.component.spec.ts" region="by" header="app/hero/hero-list.component.spec.ts"></code-example>
|
|
||||||
|
|
||||||
<hr>
|
|
||||||
|
|
@ -1,24 +1,22 @@
|
|||||||
# APIs de Utilidades de Testing
|
# Testing Utility APIs
|
||||||
|
|
||||||
Esta página describe las funciones de testing más útiles de Angular
|
This page describes the most useful Angular testing features.
|
||||||
|
|
||||||
Las funciones de testing de Angular incluyen la `TestBed` , el `ComponentFixture` y varias funciones que controlan el medio de pruebas
|
The Angular testing utilities include the `TestBed`, the `ComponentFixture`, and a handful of functions that control the test environment.
|
||||||
|
The [_TestBed_](#testbed-api-summary) and [_ComponentFixture_](#component-fixture-api-summary) classes are covered separately.
|
||||||
|
|
||||||
Las clases [_TestBed_](#testbed-api-summary) y [_ComponentFixture_](#component-fixture-api-summary) se tratan aparte.
|
Here's a summary of the stand-alone functions, in order of likely utility:
|
||||||
|
|
||||||
Este es un resumen de todas las funciones autocontenidas, en orden de posible utilidad:
|
|
||||||
|
|
||||||
<table>
|
<table>
|
||||||
<tr>
|
<tr>
|
||||||
<th>
|
<th>
|
||||||
Función
|
Function
|
||||||
</th>
|
</th>
|
||||||
<th>
|
<th>
|
||||||
Descripción
|
Description
|
||||||
</th>
|
</th>
|
||||||
</tr>
|
</tr>
|
||||||
|
|
||||||
|
|
||||||
<tr>
|
<tr>
|
||||||
<td style="vertical-align: top">
|
<td style="vertical-align: top">
|
||||||
<code>async</code>
|
<code>async</code>
|
||||||
@ -26,8 +24,8 @@ Este es un resumen de todas las funciones autocontenidas, en orden de posible ut
|
|||||||
|
|
||||||
<td>
|
<td>
|
||||||
|
|
||||||
Ejecuta el conjunto de una función test (`it`) o setup (`beforeEach`) desde una _zona de pruebas asíncrona_
|
Runs the body of a test (`it`) or setup (`beforeEach`) function within a special _async test zone_.
|
||||||
Consulta [esta discusión](guide/testing-components-scenarios#waitForAsync).
|
See [discussion above](guide/testing-components-scenarios#waitForAsync).
|
||||||
|
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
@ -39,8 +37,8 @@ Este es un resumen de todas las funciones autocontenidas, en orden de posible ut
|
|||||||
|
|
||||||
<td>
|
<td>
|
||||||
|
|
||||||
Ejecuta el conjunto de un test (`it`) desde una _zona falsa de pruebas asíncrona_ especial, permitiendo un estilo de código de flujo de control lineal.
|
Runs the body of a test (`it`) within a special _fakeAsync test zone_, enabling
|
||||||
Consulta [esta discusión](guide/testing-components-scenarios#fake-async).
|
a linear control flow coding style. See [discussion above](guide/testing-components-scenarios#fake-async).
|
||||||
|
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
@ -52,17 +50,20 @@ Este es un resumen de todas las funciones autocontenidas, en orden de posible ut
|
|||||||
|
|
||||||
<td>
|
<td>
|
||||||
|
|
||||||
Simula el paso del tiempo y completar actividades asíncronas pendientes haciendo flush tanto en el _cronómetro_ como en la _cola de micro-tareas_ desde la _zona falsa de pruebas asíncronas_
|
Simulates the passage of time and the completion of pending asynchronous activities
|
||||||
|
by flushing both _timer_ and _micro-task_ queues within the _fakeAsync test zone_.
|
||||||
|
|
||||||
<div class="alert is-helpful">
|
<div class="alert is-helpful">
|
||||||
Algún lector curioso y dedicado quizá disfrute de la lectura de esta extensa publicación en un blog:
|
|
||||||
|
The curious, dedicated reader might enjoy this lengthy blog post,
|
||||||
["_Tasks, microtasks, queues and schedules_"](https://jakearchibald.com/2015/tasks-microtasks-queues-and-schedules/).
|
["_Tasks, microtasks, queues and schedules_"](https://jakearchibald.com/2015/tasks-microtasks-queues-and-schedules/).
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
Acepta un argumento adicionar que adelanta el reloj virtual según el número especificado de milisegundos, despejando las actividades asíncronas planeadas para ese bloque de tiempo
|
Accepts an optional argument that moves the virtual clock forward
|
||||||
|
by the specified number of milliseconds,
|
||||||
Consulta [esta discusión](guide/testing-components-scenarios#tick).
|
clearing asynchronous activities scheduled within that timeframe.
|
||||||
|
See [discussion above](guide/testing-components-scenarios#tick).
|
||||||
|
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
@ -74,9 +75,9 @@ Este es un resumen de todas las funciones autocontenidas, en orden de posible ut
|
|||||||
|
|
||||||
<td>
|
<td>
|
||||||
|
|
||||||
Inyecta uno o más servicios desde la `TestBed` inyectora actual hacia una función de test.
|
Injects one or more services from the current `TestBed` injector into a test function.
|
||||||
No puede inyectar un servicio proveído por el componente en sí.
|
It cannot inject a service provided by the component itself.
|
||||||
Consulta [debugElement.injector](guide/testing-components-scenarios#get-injected-services).
|
See discussion of the [debugElement.injector](guide/testing-components-scenarios#get-injected-services).
|
||||||
|
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
@ -88,9 +89,12 @@ Este es un resumen de todas las funciones autocontenidas, en orden de posible ut
|
|||||||
|
|
||||||
<td>
|
<td>
|
||||||
|
|
||||||
Cuando un `fakeAsync()` test finaliza con tareas cronometradas pendientes (llamadas a `setTimeOut` y `setInterval` en cola), el test finaliza con un mensaje de error vacío.
|
When a `fakeAsync()` test ends with pending timer event _tasks_ (queued `setTimeOut` and `setInterval` callbacks),
|
||||||
|
the test fails with a clear error message.
|
||||||
|
|
||||||
En general, un test debería finalizar sin tareas en cola. Cuando esperamos tareas cronometradas pendientes, llamamos a `discardPeriodicTasks` para hacer flush a la cola de tareas y evitar el error.
|
In general, a test should end with no queued tasks.
|
||||||
|
When pending timer tasks are expected, call `discardPeriodicTasks` to flush the _task_ queue
|
||||||
|
and avoid the error.
|
||||||
|
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
@ -101,9 +105,13 @@ Este es un resumen de todas las funciones autocontenidas, en orden de posible ut
|
|||||||
</td>
|
</td>
|
||||||
|
|
||||||
<td>
|
<td>
|
||||||
Cuando un test `fakeAsync()` finaliza con micro-tareas pendientes como promesas sin resolver, el test finaliza con un mensaje de error vacío
|
|
||||||
|
|
||||||
En general, un test debería esperar a que acaben las micro-tareas. Cuando quedan micro-tareas pendientes en cola, llamamos a `flushMicrotasks` para hacer flush a la cola de micro-tareas y evitar el error.
|
When a `fakeAsync()` test ends with pending _micro-tasks_ such as unresolved promises,
|
||||||
|
the test fails with a clear error message.
|
||||||
|
|
||||||
|
In general, a test should wait for micro-tasks to finish.
|
||||||
|
When pending microtasks are expected, call `flushMicrotasks` to flush the _micro-task_ queue
|
||||||
|
and avoid the error.
|
||||||
|
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
@ -114,7 +122,8 @@ Este es un resumen de todas las funciones autocontenidas, en orden de posible ut
|
|||||||
</td>
|
</td>
|
||||||
|
|
||||||
<td>
|
<td>
|
||||||
Un token del proveedor que inicia la [detección automática de cambios](guide/testing-components-scenarios#automatic-change-detection).
|
|
||||||
|
A provider token for a service that turns on [automatic change detection](guide/testing-components-scenarios#automatic-change-detection).
|
||||||
|
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
@ -126,9 +135,10 @@ Este es un resumen de todas las funciones autocontenidas, en orden de posible ut
|
|||||||
|
|
||||||
<td>
|
<td>
|
||||||
|
|
||||||
Toma la instancia actual de la `TestBed`.
|
Gets the current instance of the `TestBed`.
|
||||||
Normalmente es innecesaria porque los métodos de clase estáticos de `TestBed` suelen ser suficientes.
|
Usually unnecessary because the static class methods of the `TestBed` class are typically sufficient.
|
||||||
La instancia de `TestBed` muestra algunos miembros menos comunes que no están disponibles como métodos estáticos
|
The `TestBed` instance exposes a few rarely used members that are not available as
|
||||||
|
static methods.
|
||||||
|
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
@ -136,13 +146,17 @@ Este es un resumen de todas las funciones autocontenidas, en orden de posible ut
|
|||||||
|
|
||||||
<hr>
|
<hr>
|
||||||
|
|
||||||
{@a resumen-clase-testbed}
|
{@a testbed-class-summary}
|
||||||
|
|
||||||
## Resumen de la clase _TestBed_
|
## _TestBed_ class summary
|
||||||
|
|
||||||
La clase `TestBed` es una de las utilidades de testing principales de Angular. Su API es bastante grande y puede ser sobrecogedora hasta que la has explorado, ve poco a poco. Puedes leer la parte inicial de esta guía primero para familiarizarte con lo básico antes de intentar aprender toda la API.
|
The `TestBed` class is one of the principal Angular testing utilities.
|
||||||
|
Its API is quite large and can be overwhelming until you've explored it,
|
||||||
|
a little at a time. Read the early part of this guide first
|
||||||
|
to get the basics before trying to absorb the full API.
|
||||||
|
|
||||||
La definición del módulo que pasamos a `configureTestingModule` es un subconjunto de las propiedades metadata de `@NgModule`.
|
The module definition passed to `configureTestingModule`
|
||||||
|
is a subset of the `@NgModule` metadata properties.
|
||||||
|
|
||||||
<code-example language="javascript">
|
<code-example language="javascript">
|
||||||
type TestModuleMetadata = {
|
type TestModuleMetadata = {
|
||||||
@ -155,8 +169,9 @@ La definición del módulo que pasamos a `configureTestingModule` es un subconju
|
|||||||
|
|
||||||
{@a metadata-override-object}
|
{@a metadata-override-object}
|
||||||
|
|
||||||
Cada método de sobreescribir toma un `MetadataOverride<T>` donde `T` es el tipo de metadato apropiado para el método, es decir, el parámetro de un `@NgModule`,
|
Each override method takes a `MetadataOverride<T>` where `T` is the kind of metadata
|
||||||
`@Component`, `@Directive`, o `@Pipe`.
|
appropriate to the method, that is, the parameter of an `@NgModule`,
|
||||||
|
`@Component`, `@Directive`, or `@Pipe`.
|
||||||
|
|
||||||
<code-example language="javascript">
|
<code-example language="javascript">
|
||||||
type MetadataOverride<T> = {
|
type MetadataOverride<T> = {
|
||||||
@ -166,28 +181,28 @@ Cada método de sobreescribir toma un `MetadataOverride<T>` donde `T` es el tip
|
|||||||
};
|
};
|
||||||
</code-example>
|
</code-example>
|
||||||
|
|
||||||
{@a testbed-métodos}
|
{@a testbed-methods}
|
||||||
{@a testbed-api-summary}
|
{@a testbed-api-summary}
|
||||||
|
|
||||||
La API `TestBed` consiste de métodos de clase estáticos que o actualizan o referencian una instancia global de `TestBed`.
|
The `TestBed` API consists of static class methods that either update or reference a _global_ instance of the `TestBed`.
|
||||||
|
|
||||||
Internamente, todos los métodos estáticos cubren los métodos de la instancia `TestBed` actual, lo cual también es devuelto por la función `getTestBed()`.
|
Internally, all static methods cover methods of the current runtime `TestBed` instance,
|
||||||
|
which is also returned by the `getTestBed()` function.
|
||||||
|
|
||||||
Llama a los métodos `TestBed` *desde* un `beforeEach()` para asegurarte de tener un inicio en blanco antes de cada test individual.
|
Call `TestBed` methods _within_ a `beforeEach()` to ensure a fresh start before each individual test.
|
||||||
|
|
||||||
Aquí están los métodos estáticos más importantes, en orden de posible utilidad.
|
Here are the most important static methods, in order of likely utility.
|
||||||
|
|
||||||
<table>
|
<table>
|
||||||
<tr>
|
<tr>
|
||||||
<th>
|
<th>
|
||||||
Métodos
|
Methods
|
||||||
</th>
|
</th>
|
||||||
<th>
|
<th>
|
||||||
Descripción
|
Description
|
||||||
</th>
|
</th>
|
||||||
</tr>
|
</tr>
|
||||||
|
|
||||||
|
|
||||||
<tr>
|
<tr>
|
||||||
<td style="vertical-align: top">
|
<td style="vertical-align: top">
|
||||||
<code>configureTestingModule</code>
|
<code>configureTestingModule</code>
|
||||||
@ -195,10 +210,12 @@ Aquí están los métodos estáticos más importantes, en orden de posible utili
|
|||||||
|
|
||||||
<td>
|
<td>
|
||||||
|
|
||||||
Los shims de prueba (`karma-test-shim, `browser-test-shim`) establecen el [medio de pruebas inicial](guide/testing)y un módulo de pruebas por defecto.
|
The testing shims (`karma-test-shim`, `browser-test-shim`)
|
||||||
El módulo de pruebas por defecto es configurado con declarativas básicas y algunos servicios sustitutos de Angular que cualquier tester necesitaría.
|
establish the [initial test environment](guide/testing) and a default testing module.
|
||||||
|
The default testing module is configured with basic declaratives and some Angular service substitutes that every tester needs.
|
||||||
|
|
||||||
Llama a `configureTestingModule` para refinar la configuración del módulo de pruebas para un conjunto particular de tests, añadiendo o quitando importes, declaraciones (de componentes, directivas, pipes...) y proveedores.
|
Call `configureTestingModule` to refine the testing module configuration for a particular set of tests
|
||||||
|
by adding and removing imports, declarations (of components, directives, and pipes), and providers.
|
||||||
|
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
@ -210,12 +227,12 @@ Aquí están los métodos estáticos más importantes, en orden de posible utili
|
|||||||
|
|
||||||
<td>
|
<td>
|
||||||
|
|
||||||
Compila el módulo de testing de forma asíncrona después de que hayas finalizado configurándolo.
|
Compile the testing module asynchronously after you've finished configuring it.
|
||||||
Debes llamar este método si cualquiera de los componentes de módulo de testing tiene una `templateUrl` o `styleUrls`, porque traer templates de componentes y archivos de estilo es obligatoriamente asíncrono.
|
You **must** call this method if _any_ of the testing module components have a `templateUrl`
|
||||||
|
or `styleUrls` because fetching component template and style files is necessarily asynchronous.
|
||||||
|
See [above](guide/testing-components-scenarios#compile-components).
|
||||||
|
|
||||||
Consulta [aquí](guide/testing-components-scenarios#compile-components).
|
After calling `compileComponents`, the `TestBed` configuration is frozen for the duration of the current spec.
|
||||||
|
|
||||||
Después de llamar a `compileComponents`, la configuración de `TestBed` se congela durante la especificación actual.
|
|
||||||
|
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
@ -227,8 +244,8 @@ Aquí están los métodos estáticos más importantes, en orden de posible utili
|
|||||||
|
|
||||||
<td>
|
<td>
|
||||||
|
|
||||||
Crea una instancia de un componente de tipo `T` basado en la configuración de la `TestBed` actual.
|
Create an instance of a component of type `T` based on the current `TestBed` configuration.
|
||||||
Despuest de llamar a `compileComponent`, la configuración de `TestBed` se congela durante la especificación actual.
|
After calling `compileComponent`, the `TestBed` configuration is frozen for the duration of the current spec.
|
||||||
|
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
@ -239,8 +256,9 @@ Aquí están los métodos estáticos más importantes, en orden de posible utili
|
|||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
|
|
||||||
Reemplaza metadatos del `NgModule` proporcionado. Recuerde que los módulos pueden importar otros módulos.
|
Replace metadata for the given `NgModule`. Recall that modules can import other modules.
|
||||||
El método `overrideModule` puede ir hasta el fondo del módulo testing actual para modificar alguno de estos módulos internos
|
The `overrideModule` method can reach deeply into the current testing module to
|
||||||
|
modify one of these inner modules.
|
||||||
|
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
@ -252,7 +270,8 @@ Aquí están los métodos estáticos más importantes, en orden de posible utili
|
|||||||
|
|
||||||
<td>
|
<td>
|
||||||
|
|
||||||
Reemplaza metadatos para la clase componente dada, la cual puede estar anidada dentro de un módulo interno.
|
Replace metadata for the given component class, which could be nested deeply
|
||||||
|
within an inner module.
|
||||||
|
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
@ -264,7 +283,8 @@ Aquí están los métodos estáticos más importantes, en orden de posible utili
|
|||||||
|
|
||||||
<td>
|
<td>
|
||||||
|
|
||||||
Reemplaza metadatos para la clase directiva dada, la cual puede estar anidada dentro de un módulo interno.
|
Replace metadata for the given directive class, which could be nested deeply
|
||||||
|
within an inner module.
|
||||||
|
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
@ -275,7 +295,8 @@ Aquí están los métodos estáticos más importantes, en orden de posible utili
|
|||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
|
|
||||||
Reemplaza metadatos para la clase pipe dada, la cual puede estar anidada dentro de un módulo interno.
|
Replace metadata for the given pipe class, which could be nested deeply
|
||||||
|
within an inner module.
|
||||||
|
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
@ -288,17 +309,20 @@ Aquí están los métodos estáticos más importantes, en orden de posible utili
|
|||||||
|
|
||||||
<td>
|
<td>
|
||||||
|
|
||||||
Trae un servicio del inyector `TestBed` actual.
|
Retrieve a service from the current `TestBed` injector.
|
||||||
|
|
||||||
La función `inject` normalmente es adecuada para esto, pero lanza un error si no puede proveer el servicio
|
The `inject` function is often adequate for this purpose.
|
||||||
|
But `inject` throws an error if it can't provide the service.
|
||||||
|
|
||||||
¿Qué pasa si el servicio es opcional?
|
What if the service is optional?
|
||||||
|
|
||||||
El método `TestBed.inject()` toma un segundo parámetro opcional, el objeto para devolver si Angular no encuentra el proveedor (nulo, en este ejemplo):
|
The `TestBed.inject()` method takes an optional second parameter,
|
||||||
|
the object to return if Angular can't find the provider
|
||||||
|
(`null` in this example):
|
||||||
|
|
||||||
<code-example path="testing/src/app/demo/demo.testbed.spec.ts" region="testbed-get-w-null" header="app/demo/demo.testbed.spec.ts"></code-example>
|
<code-example path="testing/src/app/demo/demo.testbed.spec.ts" region="testbed-get-w-null" header="app/demo/demo.testbed.spec.ts"></code-example>
|
||||||
|
|
||||||
Después de llamar a `TestBed.inject`, la configuración de `TestBed` se congela durante la especificación actual.
|
After calling `TestBed.inject`, the `TestBed` configuration is frozen for the duration of the current spec.
|
||||||
|
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
@ -310,14 +334,16 @@ Aquí están los métodos estáticos más importantes, en orden de posible utili
|
|||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
|
|
||||||
Inicializa el medio de testing para todo el test run.
|
Initialize the testing environment for the entire test run.
|
||||||
|
|
||||||
Los shims de pruebas (`karma-test-shim`, `browser-test-shim`) lo llaman por ti, así que no suele haber un motivo para usarlo.
|
The testing shims (`karma-test-shim`, `browser-test-shim`) call it for you
|
||||||
|
so there is rarely a reason for you to call it yourself.
|
||||||
|
|
||||||
Puedes llamar este método _exactamente una vez_. Si debes cambiar este valor por defecto en mitad de un test run, utiliza `resetTestEnvironment` primero.
|
You may call this method _exactly once_. If you must change
|
||||||
|
this default in the middle of your test run, call `resetTestEnvironment` first.
|
||||||
|
|
||||||
Especifica el compilador de fábrica Angular, un `PlatformRef` y un módulo por defecto de pruebas de Angular.
|
Specify the Angular compiler factory, a `PlatformRef`, and a default Angular testing module.
|
||||||
Existen alternativas para plataformas no basadas en navegador en el formulario general siguiente:
|
Alternatives for non-browser platforms are available in the general form
|
||||||
`@angular/platform-<platform_name>/testing/<platform_name>`.
|
`@angular/platform-<platform_name>/testing/<platform_name>`.
|
||||||
|
|
||||||
</td>
|
</td>
|
||||||
@ -329,35 +355,39 @@ Aquí están los métodos estáticos más importantes, en orden de posible utili
|
|||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
|
|
||||||
Resetea el medio de pruebas inicial, incluyendo el módulo de pruebas por defecto.
|
Reset the initial test environment, including the default testing module.
|
||||||
|
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
</table>
|
</table>
|
||||||
|
|
||||||
Algunos de los métodos de instancia de `TestBed` no son cubiertos por los métodos estáticos de clase de `TestBed`. Estos no suelen utilizarse.
|
A few of the `TestBed` instance methods are not covered by static `TestBed` _class_ methods.
|
||||||
|
These are rarely needed.
|
||||||
|
|
||||||
{@a component-fixture-api-summary}
|
{@a component-fixture-api-summary}
|
||||||
|
|
||||||
## El _ComponentFixture_
|
## The _ComponentFixture_
|
||||||
|
|
||||||
`TestBed.createComponent<T>` crea una instancia de un componente `T` y devuelve un `ComponentFixture` fuertemente tipificado para ese componente
|
The `TestBed.createComponent<T>`
|
||||||
|
creates an instance of the component `T`
|
||||||
|
and returns a strongly typed `ComponentFixture` for that component.
|
||||||
|
|
||||||
Las propiedades y métodos de `ComponentFixture` permiten acceso al componente, su representación DOM y algunos aspectos del medio Angular.
|
The `ComponentFixture` properties and methods provide access to the component,
|
||||||
|
its DOM representation, and aspects of its Angular environment.
|
||||||
|
|
||||||
{@a componentes-fixture-propiedades}
|
{@a component-fixture-properties}
|
||||||
|
|
||||||
### Propiedades de _ComponentFixture_
|
### _ComponentFixture_ properties
|
||||||
|
|
||||||
Aquí están las propiedades más importantes para testers, en orden de posible utilidad.
|
Here are the most important properties for testers, in order of likely utility.
|
||||||
|
|
||||||
<table>
|
<table>
|
||||||
<tr>
|
<tr>
|
||||||
<th>
|
<th>
|
||||||
Propiedades
|
Properties
|
||||||
</th>
|
</th>
|
||||||
<th>
|
<th>
|
||||||
Descripción
|
Description
|
||||||
</th>
|
</th>
|
||||||
</tr>
|
</tr>
|
||||||
|
|
||||||
@ -368,7 +398,7 @@ Aquí están las propiedades más importantes para testers, en orden de posible
|
|||||||
|
|
||||||
<td>
|
<td>
|
||||||
|
|
||||||
La instancia de la clase componente creada por `TestBed.createComponent`.
|
The instance of the component class created by `TestBed.createComponent`.
|
||||||
|
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
@ -380,11 +410,10 @@ Aquí están las propiedades más importantes para testers, en orden de posible
|
|||||||
|
|
||||||
<td>
|
<td>
|
||||||
|
|
||||||
El `DebugElement` asociado con el elemento raíz del componente.
|
The `DebugElement` associated with the root element of the component.
|
||||||
|
|
||||||
El `DebugElement` da información sobre el componente y su elemento DOM durante el test y debug.
|
The `debugElement` provides insight into the component and its DOM element during test and debugging.
|
||||||
|
It's a critical property for testers. The most interesting members are covered [below](#debug-element-details).
|
||||||
Es una propiedad crítica para los testers. Los miembros más interesantes están cubiertos [aquí](#debug-element-details).
|
|
||||||
|
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
@ -396,7 +425,7 @@ Aquí están las propiedades más importantes para testers, en orden de posible
|
|||||||
|
|
||||||
<td>
|
<td>
|
||||||
|
|
||||||
El elemento DOM nativo en la raíz del componente.
|
The native DOM element at the root of the component.
|
||||||
|
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
@ -408,33 +437,35 @@ Aquí están las propiedades más importantes para testers, en orden de posible
|
|||||||
|
|
||||||
<td>
|
<td>
|
||||||
|
|
||||||
El `ChangeDetectorRef` para el componente.
|
The `ChangeDetectorRef` for the component.
|
||||||
|
|
||||||
El `ChangeDetectorRef` es más valioso cuando testeamos un componente que tiene el método`ChangeDetectionStrategy.OnPush` o cuando la detección de cambios del componente está bajo tu control programático.
|
The `ChangeDetectorRef` is most valuable when testing a
|
||||||
|
component that has the `ChangeDetectionStrategy.OnPush` method
|
||||||
|
or the component's change detection is under your programmatic control.
|
||||||
|
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
</table>
|
</table>
|
||||||
|
|
||||||
{@a componente-fixture-métodos}
|
{@a component-fixture-methods}
|
||||||
|
|
||||||
### Métodos de _ComponentFixture_
|
### _ComponentFixture_ methods
|
||||||
|
|
||||||
Los métodos fixture hacen que Angular ejecute mejor ciertas tareas en el árbol de componentes. Llama a estos métodos para iniciar el comportamiento de Angular en respuesta a una acción de usuario simulada.
|
The _fixture_ methods cause Angular to perform certain tasks on the component tree.
|
||||||
|
Call these method to trigger Angular behavior in response to simulated user action.
|
||||||
|
|
||||||
Aquí están los métodos más útiles para los testers.
|
Here are the most useful methods for testers.
|
||||||
|
|
||||||
<table>
|
<table>
|
||||||
<tr>
|
<tr>
|
||||||
<th>
|
<th>
|
||||||
Métodos
|
Methods
|
||||||
</th>
|
</th>
|
||||||
<th>
|
<th>
|
||||||
Descripción
|
Description
|
||||||
</th>
|
</th>
|
||||||
</tr>
|
</tr>
|
||||||
|
|
||||||
|
|
||||||
<tr>
|
<tr>
|
||||||
<td style="vertical-align: top">
|
<td style="vertical-align: top">
|
||||||
<code>detectChanges</code>
|
<code>detectChanges</code>
|
||||||
@ -442,12 +473,15 @@ Aquí están los métodos más útiles para los testers.
|
|||||||
|
|
||||||
<td>
|
<td>
|
||||||
|
|
||||||
Inicia un ciclo de detección de cambios para el componente.
|
Trigger a change detection cycle for the component.
|
||||||
|
|
||||||
Llámalo para inicializar el componente (que llama a `ngOnInit`) y después de tu código de pruebas, cambia los valores de propiedad asociados a los datos de los componentes.
|
Call it to initialize the component (it calls `ngOnInit`) and after your
|
||||||
Angular no puede ver que has cambiado `personComponent.name` y no actualizará el `name` hasta que llames a `detectChanges`.
|
test code, change the component's data bound property values.
|
||||||
|
Angular can't see that you've changed `personComponent.name` and won't update the `name`
|
||||||
|
binding until you call `detectChanges`.
|
||||||
|
|
||||||
Ejecuta `checkNoChanges` después para confirmar que no hay actualizaciones circulares, a no se que se llame así: `detectChanges(false)`
|
Runs `checkNoChanges` afterwards to confirm that there are no circular updates unless
|
||||||
|
called as `detectChanges(false)`;
|
||||||
|
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
@ -459,13 +493,16 @@ Aquí están los métodos más útiles para los testers.
|
|||||||
|
|
||||||
<td>
|
<td>
|
||||||
|
|
||||||
Poner esto a `true` cuando quieras que el fixture detecte los cambios automáticamente.
|
|
||||||
Set this to `true` when you want the fixture to detect changes automatically.
|
Set this to `true` when you want the fixture to detect changes automatically.
|
||||||
|
|
||||||
Cuando autodetect es `true`, el fixture de pruebas llama a `detectChanges` inmediatamente después de crear el componente. Después comprueba los eventos de zona pertinentes y llama a `detectChanges` de forma acorde.
|
When autodetect is `true`, the test fixture calls `detectChanges` immediately
|
||||||
Cuando tu código de pruebas modifique los valores de propiedad de un componente de forma directa, probablemente tengas que llamar a `fixture.detectChanges` para iniciar las actualizaciones de unificación de datos.
|
after creating the component. Then it listens for pertinent zone events
|
||||||
|
and calls `detectChanges` accordingly.
|
||||||
|
When your test code modifies component property values directly,
|
||||||
|
you probably still have to call `fixture.detectChanges` to trigger data binding updates.
|
||||||
|
|
||||||
El valor por defecto es `false`. Los testers que prefieren tener un control mayor sobre el comportamiento de pruebas suelen dejarlo en `false`.
|
The default is `false`. Testers who prefer fine control over test behavior
|
||||||
|
tend to keep it `false`.
|
||||||
|
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
@ -477,9 +514,8 @@ Aquí están los métodos más útiles para los testers.
|
|||||||
|
|
||||||
<td>
|
<td>
|
||||||
|
|
||||||
Corre el programa para detectar cambios y asegurarse de que no hay cambios pendientes.
|
Do a change detection run to make sure there are no pending changes.
|
||||||
Lanza una excepción si los hay.
|
Throws an exceptions if there are.
|
||||||
|
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
|
||||||
@ -490,8 +526,8 @@ Aquí están los métodos más útiles para los testers.
|
|||||||
|
|
||||||
<td>
|
<td>
|
||||||
|
|
||||||
Si el fixture es actualmente estable, devuelve `true`.
|
If the fixture is currently _stable_, returns `true`.
|
||||||
Si hay tareas asíncronas no completadas, devuelve `false`.
|
If there are async tasks that have not completed, returns `false`.
|
||||||
|
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
@ -503,11 +539,11 @@ Aquí están los métodos más útiles para los testers.
|
|||||||
|
|
||||||
<td>
|
<td>
|
||||||
|
|
||||||
Devuelve una promesa que resuelve cuando el fixture es estable.
|
Returns a promise that resolves when the fixture is stable.
|
||||||
|
|
||||||
Para volver al testing después de completar actividad asíncrona o detección de cambios asíncronos, añade esta promesa.
|
To resume testing after completion of asynchronous activity or
|
||||||
|
asynchronous change detection, hook that promise.
|
||||||
Consulta [aquí](guide/testing-components-scenarios#when-stable).
|
See [above](guide/testing-components-scenarios#when-stable).
|
||||||
|
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
@ -519,29 +555,30 @@ Aquí están los métodos más útiles para los testers.
|
|||||||
|
|
||||||
<td>
|
<td>
|
||||||
|
|
||||||
Inicia la destrucción del componente
|
Trigger component destruction.
|
||||||
|
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
</table>
|
</table>
|
||||||
|
|
||||||
{@a debug-elementos-detalles}
|
{@a debug-element-details}
|
||||||
|
|
||||||
#### _DebugElement_
|
#### _DebugElement_
|
||||||
|
|
||||||
El `DebugElement` proporciona información crucial para la representación DOM de los componentes.
|
The `DebugElement` provides crucial insights into the component's DOM representation.
|
||||||
|
|
||||||
Desde el `DebugElement` del componente test raíz, devuelto por `fixture.debugElement`, puedes llegar a todo elemento y subárbol de componentes del fixture
|
From the test root component's `DebugElement` returned by `fixture.debugElement`,
|
||||||
|
you can walk (and query) the fixture's entire element and component subtrees.
|
||||||
|
|
||||||
Aquí están los miembros `DebugElement` más útiles para los testers, en orden de posible utilidad:
|
Here are the most useful `DebugElement` members for testers, in approximate order of utility:
|
||||||
|
|
||||||
<table>
|
<table>
|
||||||
<tr>
|
<tr>
|
||||||
<th>
|
<th>
|
||||||
Miembro
|
Member
|
||||||
</th>
|
</th>
|
||||||
<th>
|
<th>
|
||||||
Descripción
|
Description
|
||||||
</th>
|
</th>
|
||||||
</tr>
|
</tr>
|
||||||
|
|
||||||
@ -551,7 +588,8 @@ Aquí están los miembros `DebugElement` más útiles para los testers, en ord
|
|||||||
</td>
|
</td>
|
||||||
|
|
||||||
<td>
|
<td>
|
||||||
El elemento DOM correspondiente en el navegador (nulo para WebWorkers).
|
|
||||||
|
The corresponding DOM element in the browser (null for WebWorkers).
|
||||||
|
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
@ -562,7 +600,9 @@ Aquí están los miembros `DebugElement` más útiles para los testers, en ord
|
|||||||
</td>
|
</td>
|
||||||
|
|
||||||
<td>
|
<td>
|
||||||
Llamar a `query(predicate: Predicate<DebugElement>)` devuelbe el primer `DebugElement` que coincida con el [predicado](#query-predicate) a cualquier profundidad en el subárbol
|
|
||||||
|
Calling `query(predicate: Predicate<DebugElement>)` returns the first `DebugElement`
|
||||||
|
that matches the [predicate](#query-predicate) at any depth in the subtree.
|
||||||
|
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
@ -573,7 +613,9 @@ Aquí están los miembros `DebugElement` más útiles para los testers, en ord
|
|||||||
</td>
|
</td>
|
||||||
|
|
||||||
<td>
|
<td>
|
||||||
Llamar a `queryAll(predicate: Predicate<DebugElement>)` devuelve todos los `DebugElements` que coincidan con el [predicado](#query-predicate) a cualquier profundidad en el subárbol
|
|
||||||
|
Calling `queryAll(predicate: Predicate<DebugElement>)` returns all `DebugElements`
|
||||||
|
that matches the [predicate](#query-predicate) at any depth in subtree.
|
||||||
|
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
@ -584,7 +626,9 @@ Aquí están los miembros `DebugElement` más útiles para los testers, en ord
|
|||||||
</td>
|
</td>
|
||||||
|
|
||||||
<td>
|
<td>
|
||||||
El inyector de dependecia del host. Por ejemplo, el inyector de la instancia del componente del elemento
|
|
||||||
|
The host dependency injector.
|
||||||
|
For example, the root element's component instance injector.
|
||||||
|
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
@ -595,7 +639,8 @@ Aquí están los miembros `DebugElement` más útiles para los testers, en ord
|
|||||||
</td>
|
</td>
|
||||||
|
|
||||||
<td>
|
<td>
|
||||||
La instancia del componente del propio elemento, si tiene.
|
|
||||||
|
The element's own component instance, if it has one.
|
||||||
|
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
@ -607,10 +652,12 @@ Aquí están los miembros `DebugElement` más útiles para los testers, en ord
|
|||||||
|
|
||||||
<td>
|
<td>
|
||||||
|
|
||||||
Un objeto que provee contexto del padre para este elemento.
|
An object that provides parent context for this element.
|
||||||
En muchas ocasiones una instancia del componente ancestro gobierna este elemento.
|
Often an ancestor component instance that governs this element.
|
||||||
|
|
||||||
Cuando un elemento se repite en `*ngFor`, el contexto es un `NgForRow` cuya propiedad `$implicit` es el valor de la instancia de la fila. Por ejemplo, el `hero` en *ngFor="let hero of heroes"`.
|
When an element is repeated within `*ngFor`, the context is an `NgForRow` whose `$implicit`
|
||||||
|
property is the value of the row instance value.
|
||||||
|
For example, the `hero` in `*ngFor="let hero of heroes"`.
|
||||||
|
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
@ -622,12 +669,13 @@ Aquí están los miembros `DebugElement` más útiles para los testers, en ord
|
|||||||
|
|
||||||
<td>
|
<td>
|
||||||
|
|
||||||
Los hijos `DebugElement` inmediatos. Recorre el árbol descendiendo a través de los hijos.
|
The immediate `DebugElement` children. Walk the tree by descending through `children`.
|
||||||
|
|
||||||
<div class="alert is-helpful">
|
<div class="alert is-helpful">
|
||||||
|
|
||||||
`DebugElement` también tiene `childNodes`, una lista de objetos `DebugNode`.
|
`DebugElement` also has `childNodes`, a list of `DebugNode` objects.
|
||||||
`DebugElement` deriva de los objetos `DebugNode` y suele haber más nodos que elementos. Los tester normalmente ignoran los nodos planos.
|
`DebugElement` derives from `DebugNode` objects and there are often
|
||||||
|
more nodes than elements. Testers can usually ignore plain nodes.
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</td>
|
</td>
|
||||||
@ -639,7 +687,7 @@ Aquí están los miembros `DebugElement` más útiles para los testers, en ord
|
|||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
|
|
||||||
El `DebugElement` padre. Es nulo si este es el elemento raíz.
|
The `DebugElement` parent. Null if this is the root element.
|
||||||
|
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
@ -650,7 +698,8 @@ Aquí están los miembros `DebugElement` más útiles para los testers, en ord
|
|||||||
</td>
|
</td>
|
||||||
|
|
||||||
<td>
|
<td>
|
||||||
El tag name del elemento, si es que es un elemento.
|
|
||||||
|
The element tag name, if it is an element.
|
||||||
|
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
@ -661,12 +710,13 @@ Aquí están los miembros `DebugElement` más útiles para los testers, en ord
|
|||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
|
|
||||||
Inicia el evento por su nombre si hay un receptor correspondiente en la colección `listeners` del elemento.
|
Triggers the event by its name if there is a corresponding listener
|
||||||
El segundo parámetro es el _objeto evento_ esperado por el handler.
|
in the element's `listeners` collection.
|
||||||
|
The second parameter is the _event object_ expected by the handler.
|
||||||
|
See [above](guide/testing-components-scenarios#trigger-event-handler).
|
||||||
|
|
||||||
Consulta [aquí](guide/testing-components-scenarios#trigger-event-handler).
|
If the event lacks a listener or there's some other problem,
|
||||||
|
consider calling `nativeElement.dispatchEvent(eventObject)`.
|
||||||
Si el evento no tiene un receptor o hay algún problema, considera llamar a `nativeElement.dispatchEvent(eventObject)`.
|
|
||||||
|
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
@ -678,7 +728,7 @@ Aquí están los miembros `DebugElement` más útiles para los testers, en ord
|
|||||||
|
|
||||||
<td>
|
<td>
|
||||||
|
|
||||||
Los callbacks insertados al `@Output` del componente, sus propiedades y/o las propiedades de evento del elemento.
|
The callbacks attached to the component's `@Output` properties and/or the element's event properties.
|
||||||
|
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
@ -689,8 +739,9 @@ Aquí están los miembros `DebugElement` más útiles para los testers, en ord
|
|||||||
</td>
|
</td>
|
||||||
|
|
||||||
<td>
|
<td>
|
||||||
Los token de búsqueda del inyector de este componente.
|
|
||||||
Include el componente en sí mismo además de los tokens que el componente lista en la parte "proveedores" de sus metadatos.
|
This component's injector lookup tokens.
|
||||||
|
Includes the component itself plus the tokens that the component lists in its `providers` metadata.
|
||||||
|
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
@ -701,7 +752,8 @@ Aquí están los miembros `DebugElement` más útiles para los testers, en ord
|
|||||||
</td>
|
</td>
|
||||||
|
|
||||||
<td>
|
<td>
|
||||||
Dónde encontrar este elemento en el componente template fuente.
|
|
||||||
|
Where to find this element in the source component template.
|
||||||
|
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
@ -712,7 +764,9 @@ Aquí están los miembros `DebugElement` más útiles para los testers, en ord
|
|||||||
</td>
|
</td>
|
||||||
|
|
||||||
<td>
|
<td>
|
||||||
Diccionario de objetos asociados a variables locales template (e.g. `#foo`), acuñado por el nombre de la variable local
|
|
||||||
|
Dictionary of objects associated with template local variables (e.g. `#foo`),
|
||||||
|
keyed by the local variable name.
|
||||||
|
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
@ -720,20 +774,21 @@ Aquí están los miembros `DebugElement` más útiles para los testers, en ord
|
|||||||
|
|
||||||
{@a query-predicate}
|
{@a query-predicate}
|
||||||
|
|
||||||
Los métodos `DebugElement.query(predicate)` y`DebugElement.queryAll(predicate)` toman un predicado que filtra el subárbol del elemento fuente para igualar a `DebugElement`.
|
The `DebugElement.query(predicate)` and `DebugElement.queryAll(predicate)` methods take a
|
||||||
|
predicate that filters the source element's subtree for matching `DebugElement`.
|
||||||
|
|
||||||
El predicado es cualquier método que tome el `DebugElement` y devuelva un valor verdadero.
|
The predicate is any method that takes a `DebugElement` and returns a _truthy_ value.
|
||||||
|
The following example finds all `DebugElements` with a reference to a template local variable named "content":
|
||||||
El siguiente ejemplo encuentra todos los `DebugElement` con una referencia a una variable local template llamada "content":
|
|
||||||
|
|
||||||
<code-example path="testing/src/app/demo/demo.testbed.spec.ts" region="custom-predicate" header="app/demo/demo.testbed.spec.ts"></code-example>
|
<code-example path="testing/src/app/demo/demo.testbed.spec.ts" region="custom-predicate" header="app/demo/demo.testbed.spec.ts"></code-example>
|
||||||
|
|
||||||
La clase Angular `By` tiene tres métodos estáticos para predicados comunes:
|
The Angular `By` class has three static methods for common predicates:
|
||||||
|
|
||||||
- `By.all` - devuelve todos los elementos
|
- `By.all` - return all elements.
|
||||||
- `By.css(selector)` - devuelve los elementos con selectores CSS coincidentes
|
- `By.css(selector)` - return elements with matching CSS selectors.
|
||||||
- `By.directive(directive)` - devuelve elementos que Angular ha unido a una instancia de la clase directiva.
|
- `By.directive(directive)` - return elements that Angular matched to an instance of the directive class.
|
||||||
|
|
||||||
<code-example path="testing/src/app/hero/hero-list.component.spec.ts" region="by" header="app/hero/hero-list.component.spec.ts"></code-example>
|
<code-example path="testing/src/app/hero/hero-list.component.spec.ts" region="by" header="app/hero/hero-list.component.spec.ts"></code-example>
|
||||||
|
|
||||||
<hr>
|
<hr>
|
||||||
|
|
||||||
|
@ -1,58 +0,0 @@
|
|||||||
# Background processing using web workers
|
|
||||||
|
|
||||||
[Web workers](https://developer.mozilla.org/en-US/docs/Web/API/Web_Workers_API) allow you to run CPU-intensive computations in a background thread,
|
|
||||||
freeing the main thread to update the user interface.
|
|
||||||
If you find your application performs a lot of computations, such as generating CAD drawings or doing heavy geometrical calculations, using web workers can help increase your application's performance.
|
|
||||||
|
|
||||||
<div class="alert is-helpful">
|
|
||||||
|
|
||||||
The CLI does not support running Angular itself in a web worker.
|
|
||||||
|
|
||||||
</div>
|
|
||||||
|
|
||||||
## Adding a web worker
|
|
||||||
|
|
||||||
To add a web worker to an existing project, use the Angular CLI `ng generate` command.
|
|
||||||
|
|
||||||
`ng generate web-worker` *location*
|
|
||||||
|
|
||||||
You can add a web worker anywhere in your application.
|
|
||||||
For example, to add a web worker to the root component, `src/app/app.component.ts`, run the following command.
|
|
||||||
|
|
||||||
`ng generate web-worker app`
|
|
||||||
|
|
||||||
The command performs the following actions.
|
|
||||||
|
|
||||||
- Configures your project to use web workers, if it isn't already.
|
|
||||||
- Adds the following scaffold code to `src/app/app.worker.ts` to receive messages.
|
|
||||||
|
|
||||||
<code-example language="typescript" header="src/app/app.worker.ts">
|
|
||||||
addEventListener('message', ({ data }) => {
|
|
||||||
const response = `worker response to ${data}`;
|
|
||||||
postMessage(response);
|
|
||||||
});
|
|
||||||
</code-example>
|
|
||||||
|
|
||||||
- Adds the following scaffold code to `src/app/app.component.ts` to use the worker.
|
|
||||||
|
|
||||||
<code-example language="typescript" header="src/app/app.component.ts">
|
|
||||||
if (typeof Worker !== 'undefined') {
|
|
||||||
// Create a new
|
|
||||||
const worker = new Worker('./app.worker', { type: 'module' });
|
|
||||||
worker.onmessage = ({ data }) => {
|
|
||||||
console.log(`page got message: ${data}`);
|
|
||||||
};
|
|
||||||
worker.postMessage('hello');
|
|
||||||
} else {
|
|
||||||
// Web workers are not supported in this environment.
|
|
||||||
// You should add a fallback so that your program still executes correctly.
|
|
||||||
}
|
|
||||||
</code-example>
|
|
||||||
|
|
||||||
After you generate this initial scaffold, you must refactor your code to use the web worker by sending messages to and from the worker.
|
|
||||||
|
|
||||||
<div class="alert is-important">
|
|
||||||
|
|
||||||
Some environments or platforms, such as `@angular/platform-server` used in [Server-side Rendering](guide/universal), don't support web workers. To ensure that your application will work in these environments, you must provide a fallback mechanism to perform the computations that the worker would otherwise perform.
|
|
||||||
|
|
||||||
</div>
|
|
@ -1,30 +1,30 @@
|
|||||||
# Procesamiento en segundo plano utilizando web workers
|
# Background processing using web workers
|
||||||
|
|
||||||
[Web workers](https://developer.mozilla.org/en-US/docs/Web/API/Web_Workers_API) te permiten ejecutar cálculos intensivos de CPU en un subproceso en segundo plano,
|
[Web workers](https://developer.mozilla.org/en-US/docs/Web/API/Web_Workers_API) allow you to run CPU-intensive computations in a background thread,
|
||||||
liberando el hilo principal para actualizar la interfaz de usuario.
|
freeing the main thread to update the user interface.
|
||||||
Si encuentras que la aplicación realiza una gran cantidad de cálculos, como generar dibujos CAD o realizar cálculos geométricos pesados, el uso de web workers puede ayudar a aumentar el rendimiento de la aplicación.
|
If you find your application performs a lot of computations, such as generating CAD drawings or doing heavy geometrical calculations, using web workers can help increase your application's performance.
|
||||||
|
|
||||||
<div class="alert is-helpful">
|
<div class="alert is-helpful">
|
||||||
|
|
||||||
La CLI no admite la ejecución de Angular en un web worker.
|
The CLI does not support running Angular itself in a web worker.
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
## Agregando un web worker
|
## Adding a web worker
|
||||||
|
|
||||||
Para agregar un web worker a un proyecto existente, utiliza el comando de Angular `ng generate` de la CLI.
|
To add a web worker to an existing project, use the Angular CLI `ng generate` command.
|
||||||
|
|
||||||
`ng generate web-worker` *location*
|
`ng generate web-worker` *location*
|
||||||
|
|
||||||
Puedes agregar un web worker en cualquier lugar de la aplicación.
|
You can add a web worker anywhere in your application.
|
||||||
Por ejemplo, para agregar un web worker al componente raíz, `src/app/app.component.ts`, ejecuta el siguiente comando.
|
For example, to add a web worker to the root component, `src/app/app.component.ts`, run the following command.
|
||||||
|
|
||||||
`ng generate web-worker app`
|
`ng generate web-worker app`
|
||||||
|
|
||||||
El comando realiza las siguientes acciones.
|
The command performs the following actions.
|
||||||
|
|
||||||
- Configura el proyecto para que use web workers, si aún no lo está.
|
- Configures your project to use web workers, if it isn't already.
|
||||||
- Agrega el siguiente código a `src/app/app.worker.ts` para recibir mensajes.
|
- Adds the following scaffold code to `src/app/app.worker.ts` to receive messages.
|
||||||
|
|
||||||
<code-example language="typescript" header="src/app/app.worker.ts">
|
<code-example language="typescript" header="src/app/app.worker.ts">
|
||||||
addEventListener('message', ({ data }) => {
|
addEventListener('message', ({ data }) => {
|
||||||
@ -33,7 +33,7 @@ El comando realiza las siguientes acciones.
|
|||||||
});
|
});
|
||||||
</code-example>
|
</code-example>
|
||||||
|
|
||||||
- Agrega el siguiente código `src/app/app.component.ts` para usar el worker.
|
- Adds the following scaffold code to `src/app/app.component.ts` to use the worker.
|
||||||
|
|
||||||
<code-example language="typescript" header="src/app/app.component.ts">
|
<code-example language="typescript" header="src/app/app.component.ts">
|
||||||
if (typeof Worker !== 'undefined') {
|
if (typeof Worker !== 'undefined') {
|
||||||
@ -49,10 +49,10 @@ El comando realiza las siguientes acciones.
|
|||||||
}
|
}
|
||||||
</code-example>
|
</code-example>
|
||||||
|
|
||||||
Después de generar esta estructura inicial, debes refactorizar el código para usar el web worker enviando mensajes desde y hacia el worker.
|
After you generate this initial scaffold, you must refactor your code to use the web worker by sending messages to and from the worker.
|
||||||
|
|
||||||
<div class="alert is-important">
|
<div class="alert is-important">
|
||||||
|
|
||||||
Algunos entornos o plataformas, como `@angular/platform-server` utilizado en [Renderizado del lado del servidor](guide/universal), no admiten web workers. Para asegurarte de que la aplicación funcionará en estos entornos, debes proporcionar un mecanismo de reserva para realizar los cálculos que el worker realizaría de otro modo.
|
Some environments or platforms, such as `@angular/platform-server` used in [Server-side Rendering](guide/universal), don't support web workers. To ensure that your application will work in these environments, you must provide a fallback mechanism to perform the computations that the worker would otherwise perform.
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
@ -1,32 +1,32 @@
|
|||||||
# Página de colaboradores
|
# Contributors page
|
||||||
|
|
||||||
Tenemos una contabilidad oficial de quiénes están en el Angular Team, quiénes son "colaboradores de confianza" (consulte https://team.angular.io/collaborators), etc.
|
We have an official accounting of who is on the Angular Team, who are "trusted collaborators" (see https://team.angular.io/collaborators), and so on.
|
||||||
|
|
||||||
El `contributors.json` debe mantenerse para mantener nuestro" organigrama "en un solo lugar coherente.
|
The `contributors.json` should be maintained to keep our "org chart" in a single consistent place.
|
||||||
|
|
||||||
## Lista de GDE
|
## GDE listings
|
||||||
|
|
||||||
Hay dos páginas:
|
There are two pages:
|
||||||
|
|
||||||
- https://developers.google.com/experts/all/technology/angular
|
- https://developers.google.com/experts/all/technology/angular
|
||||||
(Empleados de Google: fuente en http://google3/googledata/devsite/content/en/experts/all/technology/angular.html)
|
(Googlers: source at http://google3/googledata/devsite/content/en/experts/all/technology/angular.html)
|
||||||
que es mantenido por Dawid Ostrowski basado en una hoja de cálculo
|
which is maintained by Dawid Ostrowski based on a spreadsheet
|
||||||
https://docs.google.com/spreadsheets/d/1_Ls2Kle7NxPBIG8f3OEVZ4gJZ8OCTtBxGYwMPb1TUVE/edit#gid=0.
|
https://docs.google.com/spreadsheets/d/1_Ls2Kle7NxPBIG8f3OEVZ4gJZ8OCTtBxGYwMPb1TUVE/edit#gid=0.
|
||||||
<!-- gkalpak: That URL doesn't seem to work any more. New URL: https://developers.google.com/programs/experts/directory/ (?) -->
|
<!-- gkalpak: That URL doesn't seem to work any more. New URL: https://developers.google.com/programs/experts/directory/ (?) -->
|
||||||
|
|
||||||
- Nuestro: https://angular.io/about?group=GDE que se deriva de `contributors.json`.
|
- Ours: https://angular.io/about?group=GDE which is derived from `contributors.json`.
|
||||||
|
|
||||||
Alex Eagle está investigando cómo conciliar estas dos listas.
|
Alex Eagle is investigating how to reconcile these two lists.
|
||||||
|
|
||||||
## Sobre los datos
|
## About the data
|
||||||
|
|
||||||
- Las llaves en `contributors.json` deben ser identificadores de GitHub. (La mayoría lo son actualmente, pero no todos).
|
- Keys in `contributors.json` should be GitHub handles. (Most currently are, but not all.)
|
||||||
Esto nos permitirá usar GitHub como fuente predeterminada para cosas como nombre, avatar, etc.
|
This will allow us to use GitHub as the default source for things like name, avatar, etc.
|
||||||
- Las imágenes se almacenan en `aio/content/images/bios/<picture-filename>`.
|
- Pictures are stored in `aio/content/images/bios/<picture-filename>`.
|
||||||
|
|
||||||
## Procesando los datos
|
## Processing the data
|
||||||
|
|
||||||
Instala https://stedolan.github.io/jq/ que es increíble.
|
Install https://stedolan.github.io/jq/ which is amazing.
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
for handle in $(jq keys[] --raw-output < aio/content/marketing/contributors.json)
|
for handle in $(jq keys[] --raw-output < aio/content/marketing/contributors.json)
|
||||||
@ -35,4 +35,4 @@ do echo -e "\n$handle\n---------\n"; curl --silent -H "Authorization: token ${TO
|
|||||||
done
|
done
|
||||||
```
|
```
|
||||||
|
|
||||||
Los scripts relevantes se almacenan en `aio/scripts/contributors/`.
|
Relevant scripts are stored in `aio/scripts/contributors/`.
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
<header class="marketing-banner">
|
<header class="marketing-banner">
|
||||||
<h1 class="banner-headline no-toc no-anchor">Funcionalidades y Ventajas</h1>
|
<h1 class="banner-headline no-toc no-anchor">Funcionalidades & Ventajas</h1>
|
||||||
</header>
|
</header>
|
||||||
|
|
||||||
<article>
|
<article>
|
||||||
@ -27,7 +27,7 @@
|
|||||||
<div class="feature">
|
<div class="feature">
|
||||||
<div class="feature-title">Escritorio</div>
|
<div class="feature-title">Escritorio</div>
|
||||||
<p class="text-body">Crea aplicaciones instaladas en el escritorio en Mac, Windows y Linux con los mismos
|
<p class="text-body">Crea aplicaciones instaladas en el escritorio en Mac, Windows y Linux con los mismos
|
||||||
métodos Angular que has aprendido para la web, además de la capacidad de acceder a las APIs nativas del
|
métodos Angular que ha aprendido para la web, además de la capacidad de acceder a las API nativas del
|
||||||
sistema operativo.</p>
|
sistema operativo.</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -1,19 +1,18 @@
|
|||||||
<header class="marketing-banner">
|
<header class="marketing-banner">
|
||||||
<h1 class="banner-headline no-toc no-anchor">Carpeta de prensa</h1>
|
<h1 class="banner-headline no-toc no-anchor">Press kit</h1>
|
||||||
</header>
|
</header>
|
||||||
|
|
||||||
<article class="presskit-container">
|
<article class="presskit-container">
|
||||||
<div class="presskit-row">
|
<div class="presskit-row">
|
||||||
<div class="presskit-inner">
|
<div class="presskit-inner">
|
||||||
<div>
|
<div>
|
||||||
<h2>LOGO DE ANGULAR</h2>
|
<h2>ANGULAR LOGO</h2>
|
||||||
<p>
|
<p>
|
||||||
Los gráficos del logotipo disponibles para descargar en esta página se proporcionan en
|
The logo graphics available for download on this page are provided under
|
||||||
<a class="cc-by-anchor" href="https://creativecommons.org/licenses/by/4.0/">CC BY 4.0</a>.
|
<a class="cc-by-anchor" href="https://creativecommons.org/licenses/by/4.0/">CC BY 4.0</a>.
|
||||||
Esto significa que puedes hacer lo que quieras con él, incluso imprimirlo en camisetas, crear tu
|
This means that you can pretty much do what you like with it including printing it on shirts, creating your own variations, or getting it tattooed over your navel.
|
||||||
propias variaciones, o tatuártelo sobre el ombligo.
|
|
||||||
</p>
|
</p>
|
||||||
<p>Te pedimos que no utilices el resto de los gráficos del sitio en otros contextos para evitar confusiones.</p>
|
<p>We do ask that you not use the rest of the site graphics in other contexts to avoid confusion.</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -24,15 +23,13 @@
|
|||||||
<img src="assets/images/logos/angular/angular.svg" alt="Full color logo Angular">
|
<img src="assets/images/logos/angular/angular.svg" alt="Full color logo Angular">
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<h3 class="l-space-left-3">LOGOTIPO A TODO COLOR</h3>
|
<h3 class="l-space-left-3">FULL COLOR LOGO</h3>
|
||||||
<ul class="l-space-left-3">
|
<ul class="l-space-left-3">
|
||||||
<li>
|
<li>
|
||||||
<span>Logo de Angular (png) - <a href="assets/images/logos/angular/angular.png"
|
<span>Angular Logo (png) - <a href="assets/images/logos/angular/angular.png" download>Download</a></span>
|
||||||
download>Descargar</a></span>
|
|
||||||
</li>
|
</li>
|
||||||
<li>
|
<li>
|
||||||
<span>Logo de Angular (svg) - <a href="assets/images/logos/angular/angular.svg"
|
<span>Angular Logo (svg) - <a href="assets/images/logos/angular/angular.svg" download>Download</a></span>
|
||||||
download>Descargar</a></span>
|
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
@ -47,15 +44,13 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<h3 class="l-space-left-3">LOGOTIPO DE UN COLOR</h3>
|
<h3 class="l-space-left-3">ONE COLOR LOGO</h3>
|
||||||
<ul class="l-space-left-3">
|
<ul class="l-space-left-3">
|
||||||
<li>
|
<li>
|
||||||
<span>Logo Angular en Negro (png) - <a href="assets/images/logos/angular/angular_solidBlack.png"
|
<span>Angular Logo Black (png) - <a href="assets/images/logos/angular/angular_solidBlack.png" download>Download</a></span>
|
||||||
download>Descargar</a></span>
|
|
||||||
</li>
|
</li>
|
||||||
<li>
|
<li>
|
||||||
<span>Logo Angular en Negro (svg) - <a href="assets/images/logos/angular/angular_solidBlack.svg"
|
<span>Angular Logo Black (svg) - <a href="assets/images/logos/angular/angular_solidBlack.svg" download>Download</a></span>
|
||||||
download>Descargar</a></span>
|
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
@ -66,20 +61,17 @@
|
|||||||
<div class="presskit-inner">
|
<div class="presskit-inner">
|
||||||
<div class="presskit-image-container">
|
<div class="presskit-image-container">
|
||||||
<div>
|
<div>
|
||||||
<img src="assets/images/logos/angular/angular_whiteTransparent.svg" class="transparent-img-bg"
|
<img src="assets/images/logos/angular/angular_whiteTransparent.svg" class="transparent-img-bg" alt="Transparent logo Angular">
|
||||||
alt="Transparent logo Angular">
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<h3 class="l-space-left-3">LOGOTIPO INVERSO DE UN COLOR</h3>
|
<h3 class="l-space-left-3">ONE COLOR INVERSE LOGO</h3>
|
||||||
<ul class="l-space-left-3">
|
<ul class="l-space-left-3">
|
||||||
<li>
|
<li>
|
||||||
<span>Logo de Angular Blanco Semi-Transparente (png) - <a
|
<span>Angular Logo White Semi-Transparent (png) - <a href="assets/images/logos/angular/angular_whiteTransparent.png" download>Download</a></span>
|
||||||
href="assets/images/logos/angular/angular_whiteTransparent.png" download>Descargar</a></span>
|
|
||||||
</li>
|
</li>
|
||||||
<li>
|
<li>
|
||||||
<span>Logo Angular Semi-Transparente (svg) - <a
|
<span>Angular Logo Semi-Transparent (svg) - <a href="assets/images/logos/angular/angular_whiteTransparent.svg" download>Download</a></span>
|
||||||
href="assets/images/logos/angular/angular_whiteTransparent.svg" download>Descargar</a></span>
|
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
@ -89,7 +81,7 @@
|
|||||||
<div class="presskit-row">
|
<div class="presskit-row">
|
||||||
<div class="presskit-inner">
|
<div class="presskit-inner">
|
||||||
<div>
|
<div>
|
||||||
<h2>ICONOS DE MARCA</h2>
|
<h2>BRAND ICONS</h2>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -97,18 +89,16 @@
|
|||||||
<div class="presskit-row">
|
<div class="presskit-row">
|
||||||
<div class="presskit-inner">
|
<div class="presskit-inner">
|
||||||
<div class="presskit-image-container">
|
<div class="presskit-image-container">
|
||||||
<img src="generated/images/marketing/concept-icons/animations.png" alt="Icono de Animaciones">
|
<img src="generated/images/marketing/concept-icons/animations.png" alt="Animations Icon">
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<h3 class="l-space-left-3">ANIMACIONES</h3>
|
<h3 class="l-space-left-3">ANIMATIONS</h3>
|
||||||
<ul class="l-space-left-3">
|
<ul class="l-space-left-3">
|
||||||
<li>
|
<li>
|
||||||
<span>Icono de Animaciones (png) - <a href="generated/images/marketing/concept-icons/animations.png"
|
<span>Animations Icon (png) - <a href="generated/images/marketing/concept-icons/animations.png" download>Download</a></span>
|
||||||
download>Descargar</a></span>
|
|
||||||
</li>
|
</li>
|
||||||
<li>
|
<li>
|
||||||
<span>Icono de Animaciones (svg) - <a href="generated/images/marketing/concept-icons/animations.svg"
|
<span>Animations Icon (svg) - <a href="generated/images/marketing/concept-icons/animations.svg" download>Download</a></span>
|
||||||
download>Descargar</a></span>
|
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
@ -118,18 +108,16 @@
|
|||||||
<div class="presskit-row">
|
<div class="presskit-row">
|
||||||
<div class="presskit-inner">
|
<div class="presskit-inner">
|
||||||
<div class="presskit-image-container">
|
<div class="presskit-image-container">
|
||||||
<img src="generated/images/marketing/concept-icons/augury.png" alt="Icono de Augury">
|
<img src="generated/images/marketing/concept-icons/augury.png" alt="Augury Icon">
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<h3 class="l-space-left-3">AUGURY</h3>
|
<h3 class="l-space-left-3">AUGURY</h3>
|
||||||
<ul class="l-space-left-3">
|
<ul class="l-space-left-3">
|
||||||
<li>
|
<li>
|
||||||
<span>Icono de Augury (png) - <a href="generated/images/marketing/concept-icons/augury.png"
|
<span>Augury Icon (png) - <a href="generated/images/marketing/concept-icons/augury.png" download>Download</a></span>
|
||||||
download>Descargar</a></span>
|
|
||||||
</li>
|
</li>
|
||||||
<li>
|
<li>
|
||||||
<span>Icono de Augury (svg) - <a href="generated/images/marketing/concept-icons/augury.svg"
|
<span>Augury Icon (svg) - <a href="generated/images/marketing/concept-icons/augury.svg" download>Download</a></span>
|
||||||
download>Descargar</a></span>
|
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
@ -139,18 +127,16 @@
|
|||||||
<div class="presskit-row">
|
<div class="presskit-row">
|
||||||
<div class="presskit-inner">
|
<div class="presskit-inner">
|
||||||
<div class="presskit-image-container">
|
<div class="presskit-image-container">
|
||||||
<img src="generated/images/marketing/concept-icons/cdk.png" alt="Icono de CDK">
|
<img src="generated/images/marketing/concept-icons/cdk.png" alt="CDK Icon">
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<h3 class="l-space-left-3">KIT DE DESARROLLO DE COMPONENTES (CDK)</h3>
|
<h3 class="l-space-left-3">COMPONENT DEV KIT (CDK)</h3>
|
||||||
<ul class="l-space-left-3">
|
<ul class="l-space-left-3">
|
||||||
<li>
|
<li>
|
||||||
<span>Icono de CDK (png) - <a href="generated/images/marketing/concept-icons/cdk.png"
|
<span>CDK Icon (png) - <a href="generated/images/marketing/concept-icons/cdk.png" download>Download</a></span>
|
||||||
download>Descargar</a></span>
|
|
||||||
</li>
|
</li>
|
||||||
<li>
|
<li>
|
||||||
<span>Icono de CDK (svg) - <a href="generated/images/marketing/concept-icons/cdk.svg"
|
<span>CDK Icon (svg) - <a href="generated/images/marketing/concept-icons/cdk.svg" download>Download</a></span>
|
||||||
download>Descargar</a></span>
|
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
@ -160,18 +146,16 @@
|
|||||||
<div class="presskit-row">
|
<div class="presskit-row">
|
||||||
<div class="presskit-inner">
|
<div class="presskit-inner">
|
||||||
<div class="presskit-image-container">
|
<div class="presskit-image-container">
|
||||||
<img src="generated/images/marketing/concept-icons/cli.png" alt="Icono de el CLI">
|
<img src="generated/images/marketing/concept-icons/cli.png" alt="CLI Icon">
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<h3 class="l-space-left-3">CLI</h3>
|
<h3 class="l-space-left-3">CLI</h3>
|
||||||
<ul class="l-space-left-3">
|
<ul class="l-space-left-3">
|
||||||
<li>
|
<li>
|
||||||
<span>Icono de el CLI (png) - <a href="generated/images/marketing/concept-icons/cli.png"
|
<span>CLI Icon (png) - <a href="generated/images/marketing/concept-icons/cli.png" download>Download</a></span>
|
||||||
download>Descargar</a></span>
|
|
||||||
</li>
|
</li>
|
||||||
<li>
|
<li>
|
||||||
<span>Icono de el CLI (svg) - <a href="generated/images/marketing/concept-icons/cli.svg"
|
<span>CLI Icon (svg) - <a href="generated/images/marketing/concept-icons/cli.svg" download>Download</a></span>
|
||||||
download>Descargar</a></span>
|
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
@ -181,18 +165,16 @@
|
|||||||
<div class="presskit-row">
|
<div class="presskit-row">
|
||||||
<div class="presskit-inner">
|
<div class="presskit-inner">
|
||||||
<div class="presskit-image-container">
|
<div class="presskit-image-container">
|
||||||
<img src="generated/images/marketing/concept-icons/compiler.png" alt="Icono de Compilador">
|
<img src="generated/images/marketing/concept-icons/compiler.png" alt="Compiler Icon">
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<h3 class="l-space-left-3">COMPILADOR</h3>
|
<h3 class="l-space-left-3">COMPILER</h3>
|
||||||
<ul class="l-space-left-3">
|
<ul class="l-space-left-3">
|
||||||
<li>
|
<li>
|
||||||
<span>Icono de Compilador (png) - <a href="generated/images/marketing/concept-icons/compiler.png"
|
<span>Compiler Icon (png) - <a href="generated/images/marketing/concept-icons/compiler.png" download>Download</a></span>
|
||||||
download>Descargar</a></span>
|
|
||||||
</li>
|
</li>
|
||||||
<li>
|
<li>
|
||||||
<span>Icono de Compilador (svg) - <a href="generated/images/marketing/concept-icons/compiler.svg"
|
<span>Compiler Icon (svg) - <a href="generated/images/marketing/concept-icons/compiler.svg" download>Download</a></span>
|
||||||
download>Descargar</a></span>
|
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
@ -202,18 +184,16 @@
|
|||||||
<div class="presskit-row">
|
<div class="presskit-row">
|
||||||
<div class="presskit-inner">
|
<div class="presskit-inner">
|
||||||
<div class="presskit-image-container">
|
<div class="presskit-image-container">
|
||||||
<img src="generated/images/marketing/concept-icons/components.png" alt="Icono de Componentes Web">
|
<img src="generated/images/marketing/concept-icons/components.png" alt="Components Icon">
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<h3 class="l-space-left-3">COMPONENTES WEB</h3>
|
<h3 class="l-space-left-3">WEB COMPONENTS</h3>
|
||||||
<ul class="l-space-left-3">
|
<ul class="l-space-left-3">
|
||||||
<li>
|
<li>
|
||||||
<span>Icono de Componentes Web (png) - <a href="generated/images/marketing/concept-icons/components.png"
|
<span>Web Components Icon (png) - <a href="generated/images/marketing/concept-icons/components.png" download>Download</a></span>
|
||||||
download>Descargar</a></span>
|
|
||||||
</li>
|
</li>
|
||||||
<li>
|
<li>
|
||||||
<span>Icono de Componentes Web (svg) - <a href="generated/images/marketing/concept-icons/components.svg"
|
<span>Web Components Icon (svg) - <a href="generated/images/marketing/concept-icons/components.svg" download>Download</a></span>
|
||||||
download>Descargar</a></span>
|
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
@ -223,18 +203,16 @@
|
|||||||
<div class="presskit-row">
|
<div class="presskit-row">
|
||||||
<div class="presskit-inner">
|
<div class="presskit-inner">
|
||||||
<div class="presskit-image-container">
|
<div class="presskit-image-container">
|
||||||
<img src="generated/images/marketing/concept-icons/forms.png" alt="Icono de Formularios">
|
<img src="generated/images/marketing/concept-icons/forms.png" alt="Forms Icon">
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<h3 class="l-space-left-3">FORMULARIOS</h3>
|
<h3 class="l-space-left-3">FORMS</h3>
|
||||||
<ul class="l-space-left-3">
|
<ul class="l-space-left-3">
|
||||||
<li>
|
<li>
|
||||||
<span>Icono de Formularios (png) - <a href="generated/images/marketing/concept-icons/forms.png"
|
<span>Forms Icon (png) - <a href="generated/images/marketing/concept-icons/forms.png" download>Download</a></span>
|
||||||
download>Descargar</a></span>
|
|
||||||
</li>
|
</li>
|
||||||
<li>
|
<li>
|
||||||
<span>Icono de Formularios (svg) - <a href="generated/images/marketing/concept-icons/forms.svg"
|
<span>Forms Icon (svg) - <a href="generated/images/marketing/concept-icons/forms.svg" download>Download</a></span>
|
||||||
download>Descargar</a></span>
|
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
@ -244,18 +222,16 @@
|
|||||||
<div class="presskit-row">
|
<div class="presskit-row">
|
||||||
<div class="presskit-inner">
|
<div class="presskit-inner">
|
||||||
<div class="presskit-image-container">
|
<div class="presskit-image-container">
|
||||||
<img src="generated/images/marketing/concept-icons/http.png" alt="Icono de HTTP">
|
<img src="generated/images/marketing/concept-icons/http.png" alt="HTTP Icon">
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<h3 class="l-space-left-3">HTTP</h3>
|
<h3 class="l-space-left-3">HTTP</h3>
|
||||||
<ul class="l-space-left-3">
|
<ul class="l-space-left-3">
|
||||||
<li>
|
<li>
|
||||||
<span>Icono de HTTP (png) - <a href="generated/images/marketing/concept-icons/http.png"
|
<span>HTTP Icon (png) - <a href="generated/images/marketing/concept-icons/http.png" download>Download</a></span>
|
||||||
download>Descargar</a></span>
|
|
||||||
</li>
|
</li>
|
||||||
<li>
|
<li>
|
||||||
<span>Icono de HTTP (svg) - <a href="generated/images/marketing/concept-icons/http.svg"
|
<span>HTTP Icon (svg) - <a href="generated/images/marketing/concept-icons/http.svg" download>Download</a></span>
|
||||||
download>Descargar</a></span>
|
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
@ -265,18 +241,16 @@
|
|||||||
<div class="presskit-row">
|
<div class="presskit-row">
|
||||||
<div class="presskit-inner">
|
<div class="presskit-inner">
|
||||||
<div class="presskit-image-container">
|
<div class="presskit-image-container">
|
||||||
<img src="generated/images/marketing/concept-icons/i18n.png" alt="Icono de i18n">
|
<img src="generated/images/marketing/concept-icons/i18n.png" alt="i18n Icon">
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<h3 class="l-space-left-3">i18n</h3>
|
<h3 class="l-space-left-3">i18n</h3>
|
||||||
<ul class="l-space-left-3">
|
<ul class="l-space-left-3">
|
||||||
<li>
|
<li>
|
||||||
<span>Icono de i18n (png) - <a href="generated/images/marketing/concept-icons/i18n.png"
|
<span>HTTP Icon (png) - <a href="generated/images/marketing/concept-icons/i18n.png" download>Download</a></span>
|
||||||
download>Descargar</a></span>
|
|
||||||
</li>
|
</li>
|
||||||
<li>
|
<li>
|
||||||
<span>Icono de i18n (svg) - <a href="generated/images/marketing/concept-icons/i18n.svg"
|
<span>HTTP Icon (svg) - <a href="generated/images/marketing/concept-icons/i18n.svg" download>Download</a></span>
|
||||||
download>Descargar</a></span>
|
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
@ -286,18 +260,16 @@
|
|||||||
<div class="presskit-row">
|
<div class="presskit-row">
|
||||||
<div class="presskit-inner">
|
<div class="presskit-inner">
|
||||||
<div class="presskit-image-container">
|
<div class="presskit-image-container">
|
||||||
<img src="generated/images/marketing/concept-icons/karma.png" alt="Icono de Karma">
|
<img src="generated/images/marketing/concept-icons/karma.png" alt="Karma Icon">
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<h3 class="l-space-left-3">KARMA</h3>
|
<h3 class="l-space-left-3">KARMA</h3>
|
||||||
<ul class="l-space-left-3">
|
<ul class="l-space-left-3">
|
||||||
<li>
|
<li>
|
||||||
<span>Icono de Karma (png) - <a href="generated/images/marketing/concept-icons/karma.png"
|
<span>Karma Icon (png) - <a href="generated/images/marketing/concept-icons/karma.png" download>Download</a></span>
|
||||||
download>Descargar</a></span>
|
|
||||||
</li>
|
</li>
|
||||||
<li>
|
<li>
|
||||||
<span>Icono de Karma (svg) - <a href="generated/images/marketing/concept-icons/karma.svg"
|
<span>Karma Icon (svg) - <a href="generated/images/marketing/concept-icons/karma.svg" download>Download</a></span>
|
||||||
download>Descargar</a></span>
|
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
@ -307,18 +279,16 @@
|
|||||||
<div class="presskit-row">
|
<div class="presskit-row">
|
||||||
<div class="presskit-inner">
|
<div class="presskit-inner">
|
||||||
<div class="presskit-image-container">
|
<div class="presskit-image-container">
|
||||||
<img src="generated/images/marketing/concept-icons/labs.png" alt="Icono de Labs">
|
<img src="generated/images/marketing/concept-icons/labs.png" alt="Labs Icon">
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<h3 class="l-space-left-3">LABS</h3>
|
<h3 class="l-space-left-3">LABS</h3>
|
||||||
<ul class="l-space-left-3">
|
<ul class="l-space-left-3">
|
||||||
<li>
|
<li>
|
||||||
<span>Icono de Labs (png) - <a href="generated/images/marketing/concept-icons/labs.png"
|
<span>Labs Icon (png) - <a href="generated/images/marketing/concept-icons/labs.png" download>Download</a></span>
|
||||||
download>Descargar</a></span>
|
|
||||||
</li>
|
</li>
|
||||||
<li>
|
<li>
|
||||||
<span>Icono de Labs (svg) - <a href="generated/images/marketing/concept-icons/labs.svg"
|
<span>Labs Icon (svg) - <a href="generated/images/marketing/concept-icons/labs.svg" download>Download</a></span>
|
||||||
download>Descargar</a></span>
|
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
@ -328,18 +298,16 @@
|
|||||||
<div class="presskit-row">
|
<div class="presskit-row">
|
||||||
<div class="presskit-inner">
|
<div class="presskit-inner">
|
||||||
<div class="presskit-image-container">
|
<div class="presskit-image-container">
|
||||||
<img src="generated/images/marketing/concept-icons/language-services.png" alt="Icono de Language Services">
|
<img src="generated/images/marketing/concept-icons/language-services.png" alt="Language Services Icon">
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<h3 class="l-space-left-3">LANGUAGE SERVICES</h3>
|
<h3 class="l-space-left-3">LANGUAGE SERVICES</h3>
|
||||||
<ul class="l-space-left-3">
|
<ul class="l-space-left-3">
|
||||||
<li>
|
<li>
|
||||||
<span>Icono de Language Services (png) - <a
|
<span>Language Services Icon (png) - <a href="generated/images/marketing/concept-icons/language-services.png" download>Download</a></span>
|
||||||
href="generated/images/marketing/concept-icons/language-services.png" download>Descargar</a></span>
|
|
||||||
</li>
|
</li>
|
||||||
<li>
|
<li>
|
||||||
<span>Icono de Language Services (svg) - <a
|
<span>Language Services Icon (svg) - <a href="generated/images/marketing/concept-icons/language-services.svg" download>Download</a></span>
|
||||||
href="generated/images/marketing/concept-icons/language-services.svg" download>Descargar</a></span>
|
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
@ -349,18 +317,16 @@
|
|||||||
<div class="presskit-row">
|
<div class="presskit-row">
|
||||||
<div class="presskit-inner">
|
<div class="presskit-inner">
|
||||||
<div class="presskit-image-container">
|
<div class="presskit-image-container">
|
||||||
<img src="generated/images/marketing/concept-icons/material.png" alt="Icono de Material">
|
<img src="generated/images/marketing/concept-icons/material.png" alt="Material Icon">
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<h3 class="l-space-left-3">MATERIAL</h3>
|
<h3 class="l-space-left-3">MATERIAL</h3>
|
||||||
<ul class="l-space-left-3">
|
<ul class="l-space-left-3">
|
||||||
<li>
|
<li>
|
||||||
<span>Icono de material (png) - <a href="generated/images/marketing/concept-icons/material.png"
|
<span>Material Icon (png) - <a href="generated/images/marketing/concept-icons/material.png" download>Download</a></span>
|
||||||
download>Descargar</a></span>
|
|
||||||
</li>
|
</li>
|
||||||
<li>
|
<li>
|
||||||
<span>Icono de material (svg) - <a href="generated/images/marketing/concept-icons/material.svg"
|
<span>Material Icon (svg) - <a href="generated/images/marketing/concept-icons/material.svg" download>Download</a></span>
|
||||||
download>Descargar</a></span>
|
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
@ -370,18 +336,16 @@
|
|||||||
<div class="presskit-row">
|
<div class="presskit-row">
|
||||||
<div class="presskit-inner">
|
<div class="presskit-inner">
|
||||||
<div class="presskit-image-container">
|
<div class="presskit-image-container">
|
||||||
<img src="generated/images/marketing/concept-icons/protractor.png" alt="Icono de Protractor">
|
<img src="generated/images/marketing/concept-icons/protractor.png" alt="Protractor Icon">
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<h3 class="l-space-left-3">PROTRACTOR</h3>
|
<h3 class="l-space-left-3">PROTRACTOR</h3>
|
||||||
<ul class="l-space-left-3">
|
<ul class="l-space-left-3">
|
||||||
<li>
|
<li>
|
||||||
<span>Icono de Protractor (png) - <a href="generated/images/marketing/concept-icons/protractor.png"
|
<span>Protractor Icon (png) - <a href="generated/images/marketing/concept-icons/protractor.png" download>Download</a></span>
|
||||||
download>Descargar</a></span>
|
|
||||||
</li>
|
</li>
|
||||||
<li>
|
<li>
|
||||||
<span>Icono de Protractor (svg) - <a href="generated/images/marketing/concept-icons/protractor.svg"
|
<span>Protractor Icon (svg) - <a href="generated/images/marketing/concept-icons/protractor.svg" download>Download</a></span>
|
||||||
download>Descargar</a></span>
|
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
@ -391,18 +355,16 @@
|
|||||||
<div class="presskit-row">
|
<div class="presskit-row">
|
||||||
<div class="presskit-inner">
|
<div class="presskit-inner">
|
||||||
<div class="presskit-image-container">
|
<div class="presskit-image-container">
|
||||||
<img src="generated/images/marketing/concept-icons/pwa.png" alt="Icono de PWA">
|
<img src="generated/images/marketing/concept-icons/pwa.png" alt="PWA Icon">
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<h3 class="l-space-left-3">PWA</h3>
|
<h3 class="l-space-left-3">PWA</h3>
|
||||||
<ul class="l-space-left-3">
|
<ul class="l-space-left-3">
|
||||||
<li>
|
<li>
|
||||||
<span>Icono de PWA (png) - <a href="generated/images/marketing/concept-icons/pwa.png"
|
<span>PWA Icon (png) - <a href="generated/images/marketing/concept-icons/pwa.png" download>Download</a></span>
|
||||||
download>Descargar</a></span>
|
|
||||||
</li>
|
</li>
|
||||||
<li>
|
<li>
|
||||||
<span>Icono de PWA (svg) - <a href="generated/images/marketing/concept-icons/pwa.svg"
|
<span>PWA Icon (svg) - <a href="generated/images/marketing/concept-icons/pwa.svg" download>Download</a></span>
|
||||||
download>Descargar</a></span>
|
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
@ -412,18 +374,16 @@
|
|||||||
<div class="presskit-row">
|
<div class="presskit-row">
|
||||||
<div class="presskit-inner">
|
<div class="presskit-inner">
|
||||||
<div class="presskit-image-container">
|
<div class="presskit-image-container">
|
||||||
<img src="generated/images/marketing/concept-icons/router.png" alt="Icono de Router">
|
<img src="generated/images/marketing/concept-icons/router.png" alt="Router Icon">
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<h3 class="l-space-left-3">ROUTER</h3>
|
<h3 class="l-space-left-3">ROUTER</h3>
|
||||||
<ul class="l-space-left-3">
|
<ul class="l-space-left-3">
|
||||||
<li>
|
<li>
|
||||||
<span>Icono de Router (png) - <a href="generated/images/marketing/concept-icons/router.png"
|
<span>Router Icon (png) - <a href="generated/images/marketing/concept-icons/router.png" download>Download</a></span>
|
||||||
download>Descargar</a></span>
|
|
||||||
</li>
|
</li>
|
||||||
<li>
|
<li>
|
||||||
<span>Icono de Router (svg) - <a href="generated/images/marketing/concept-icons/router.svg"
|
<span>Router Icon (svg) - <a href="generated/images/marketing/concept-icons/router.svg" download>Download</a></span>
|
||||||
download>Descargar</a></span>
|
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
@ -433,18 +393,16 @@
|
|||||||
<div class="presskit-row">
|
<div class="presskit-row">
|
||||||
<div class="presskit-inner">
|
<div class="presskit-inner">
|
||||||
<div class="presskit-image-container">
|
<div class="presskit-image-container">
|
||||||
<img src="generated/images/marketing/concept-icons/universal.png" alt="Icono Universal">
|
<img src="generated/images/marketing/concept-icons/universal.png" alt="Universal Icon">
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<h3 class="l-space-left-3">UNIVERSAL</h3>
|
<h3 class="l-space-left-3">UNIVERSAL</h3>
|
||||||
<ul class="l-space-left-3">
|
<ul class="l-space-left-3">
|
||||||
<li>
|
<li>
|
||||||
<span>Icono Universal (png) - <a href="generated/images/marketing/concept-icons/universal.png"
|
<span>Universal Icon (png) - <a href="generated/images/marketing/concept-icons/universal.png" download>Download</a></span>
|
||||||
download>Descargar</a></span>
|
|
||||||
</li>
|
</li>
|
||||||
<li>
|
<li>
|
||||||
<span>Icono Universal (svg) - <a href="generated/images/marketing/concept-icons/universal.svg"
|
<span>Universal Icon (svg) - <a href="generated/images/marketing/concept-icons/universal.svg" download>Download</a></span>
|
||||||
download>Descargar</a></span>
|
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
@ -454,7 +412,7 @@
|
|||||||
<div class="presskit-row">
|
<div class="presskit-row">
|
||||||
<div class="presskit-inner">
|
<div class="presskit-inner">
|
||||||
<div>
|
<div>
|
||||||
<h2>ICONOS DE CONCEPTO Y CARACTERÍSTICAS</h2>
|
<h2>CONCEPT & FEATURE ICONS</h2>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -462,19 +420,16 @@
|
|||||||
<div class="presskit-row">
|
<div class="presskit-row">
|
||||||
<div class="presskit-inner">
|
<div class="presskit-inner">
|
||||||
<div class="presskit-image-container">
|
<div class="presskit-image-container">
|
||||||
<img src="generated/images/marketing/concept-icons/dependency-injection.png"
|
<img src="generated/images/marketing/concept-icons/dependency-injection.png" alt="Dependency Injection Icon">
|
||||||
alt="Icono de inyección de dependencia">
|
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<h3 class="l-space-left-3">INYECCIÓN DE DEPENDENCIA</h3>
|
<h3 class="l-space-left-3">DEPENDENCY INJECTION</h3>
|
||||||
<ul class="l-space-left-3">
|
<ul class="l-space-left-3">
|
||||||
<li>
|
<li>
|
||||||
<span>Icono de inyección de dependencia (png) - <a
|
<span>Dependency Injection Icon (png) - <a href="generated/images/marketing/concept-icons/dependency-injection.png" download>Download</a></span>
|
||||||
href="generated/images/marketing/concept-icons/dependency-injection.png" download>Descargar</a></span>
|
|
||||||
</li>
|
</li>
|
||||||
<li>
|
<li>
|
||||||
<span>Icono de inyección de dependencia (svg) - <a
|
<span>Dependency Injection Icon (svg) - <a href="generated/images/marketing/concept-icons/dependency-injection.svg" download>Download</a></span>
|
||||||
href="generated/images/marketing/concept-icons/dependency-injection.svg" download>Descargar</a></span>
|
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
@ -484,18 +439,16 @@
|
|||||||
<div class="presskit-row">
|
<div class="presskit-row">
|
||||||
<div class="presskit-inner">
|
<div class="presskit-inner">
|
||||||
<div class="presskit-image-container">
|
<div class="presskit-image-container">
|
||||||
<img src="generated/images/marketing/concept-icons/lazy-loading.png" alt="Icono de carga diferida">
|
<img src="generated/images/marketing/concept-icons/lazy-loading.png" alt="Lazy Loading Icon">
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<h3 class="l-space-left-3">LAZY LOADING</h3>
|
<h3 class="l-space-left-3">LAZY LOADING</h3>
|
||||||
<ul class="l-space-left-3">
|
<ul class="l-space-left-3">
|
||||||
<li>
|
<li>
|
||||||
<span>Icono de carga diferida (png) - <a href="generated/images/marketing/concept-icons/lazy-loading.png"
|
<span>Lazy Loading Icon (png) - <a href="generated/images/marketing/concept-icons/lazy-loading.png" download>Download</a></span>
|
||||||
download>Descargar</a></span>
|
|
||||||
</li>
|
</li>
|
||||||
<li>
|
<li>
|
||||||
<span>Icono de carga diferida (svg) - <a href="generated/images/marketing/concept-icons/lazy-loading.svg"
|
<span>Lazy Loading Icon (svg) - <a href="generated/images/marketing/concept-icons/lazy-loading.svg" download>Download</a></span>
|
||||||
download>Descargar</a></span>
|
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
@ -505,18 +458,16 @@
|
|||||||
<div class="presskit-row">
|
<div class="presskit-row">
|
||||||
<div class="presskit-inner">
|
<div class="presskit-inner">
|
||||||
<div class="presskit-image-container">
|
<div class="presskit-image-container">
|
||||||
<img src="generated/images/marketing/concept-icons/libraries.png" alt="Icono de bibliotecas">
|
<img src="generated/images/marketing/concept-icons/libraries.png" alt="Libraries Icon">
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<h3 class="l-space-left-3">Librerías</h3>
|
<h3 class="l-space-left-3">LIBRARIES</h3>
|
||||||
<ul class="l-space-left-3">
|
<ul class="l-space-left-3">
|
||||||
<li>
|
<li>
|
||||||
<span>Icono de bibliotecas (png) - <a href="generated/images/marketing/concept-icons/libraries.png"
|
<span>Libraries Icon (png) - <a href="generated/images/marketing/concept-icons/libraries.png" download>Download</a></span>
|
||||||
download>Descargar</a></span>
|
|
||||||
</li>
|
</li>
|
||||||
<li>
|
<li>
|
||||||
<span>Icono de librerías (svg) - <a href="generated/images/marketing/concept-icons/libraries.svg"
|
<span>Libraries Icon (svg) - <a href="generated/images/marketing/concept-icons/libraries.svg" download>Download</a></span>
|
||||||
download>Descargar</a></span>
|
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
@ -526,18 +477,16 @@
|
|||||||
<div class="presskit-row">
|
<div class="presskit-row">
|
||||||
<div class="presskit-inner">
|
<div class="presskit-inner">
|
||||||
<div class="presskit-image-container">
|
<div class="presskit-image-container">
|
||||||
<img src="generated/images/marketing/concept-icons/performance.png" alt="Icono de rendimiento">
|
<img src="generated/images/marketing/concept-icons/performance.png" alt="Performance Icon">
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<h3 class="l-space-left-3">RENDIMIENTO</h3>
|
<h3 class="l-space-left-3">PERFORMANCE</h3>
|
||||||
<ul class="l-space-left-3">
|
<ul class="l-space-left-3">
|
||||||
<li>
|
<li>
|
||||||
<span>Icono de rendimiento (png) - <a href="generated/images/marketing/concept-icons/performance.png"
|
<span>Performance Icon (png) - <a href="generated/images/marketing/concept-icons/performance.png" download>Download</a></span>
|
||||||
download>Descargar</a></span>
|
|
||||||
</li>
|
</li>
|
||||||
<li>
|
<li>
|
||||||
<span>Icono de rendimiento (svg) - <a href="generated/images/marketing/concept-icons/performance.svg"
|
<span>Performance Icon (svg) - <a href="generated/images/marketing/concept-icons/performance.svg" download>Download</a></span>
|
||||||
download>Descargar</a></span>
|
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
@ -547,18 +496,16 @@
|
|||||||
<div class="presskit-row">
|
<div class="presskit-row">
|
||||||
<div class="presskit-inner">
|
<div class="presskit-inner">
|
||||||
<div class="presskit-image-container">
|
<div class="presskit-image-container">
|
||||||
<img src="generated/images/marketing/concept-icons/templates.png" alt="Icono de plantillas">
|
<img src="generated/images/marketing/concept-icons/templates.png" alt="Templates Icon">
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<h3 class="l-space-left-3">PLANTILLAS</h3>
|
<h3 class="l-space-left-3">TEMPLATES</h3>
|
||||||
<ul class="l-space-left-3">
|
<ul class="l-space-left-3">
|
||||||
<li>
|
<li>
|
||||||
<span>Icono de plantillas (png) - <a href="generated/images/marketing/concept-icons/templates.png"
|
<span>Templates Icon (png) - <a href="generated/images/marketing/concept-icons/templates.png" download>Download</a></span>
|
||||||
download>Descargar</a></span>
|
|
||||||
</li>
|
</li>
|
||||||
<li>
|
<li>
|
||||||
<span>Icono de plantillas (svg) - <a href="generated/images/marketing/concept-icons/templates.svg"
|
<span>Templates Icon (svg) - <a href="generated/images/marketing/concept-icons/templates.svg" download>Download</a></span>
|
||||||
download>Descargar</a></span>
|
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
@ -568,8 +515,8 @@
|
|||||||
<div class="presskit-row">
|
<div class="presskit-row">
|
||||||
<div class="presskit-inner">
|
<div class="presskit-inner">
|
||||||
<div>
|
<div>
|
||||||
<h2>PRENSA Y MEDIOS </h2>
|
<h2>PRESS AND MEDIA</h2>
|
||||||
<p> Para consultas sobre prensa y medios, contáctenos en
|
<p>For inquiries regarding press and media please contact us at
|
||||||
<a href="mailto:press@angular.io">press@angular.io</a>.</p>
|
<a href="mailto:press@angular.io">press@angular.io</a>.</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -577,103 +524,88 @@
|
|||||||
|
|
||||||
<style>
|
<style>
|
||||||
div.bullets ul {
|
div.bullets ul {
|
||||||
list-style-type: disc !important;
|
list-style-type: disc !important; margin-left: 1em !important;
|
||||||
margin-left: 1em !important;
|
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
<div class="presskit-row">
|
<div class="presskit-row">
|
||||||
<div class="presskit-inner">
|
<div class="presskit-inner">
|
||||||
<div class="bullets">
|
<div class="bullets">
|
||||||
<h2>NOMBRES DE MARCAS</h2>
|
<h2>BRAND NAMES</h2>
|
||||||
<h3>Angular</h3>
|
<h3>Angular</h3>
|
||||||
<p>El Nombre <b>Angular</b> representa el trabajo y las promesas que le proporcionó el equipo de Angular.</p>
|
<p>The name <b>Angular</b> represents the work and promises provided to you by the Angular team.</p>
|
||||||
|
|
||||||
<p> Cuando no se especifica, se supone que Angular se refiere a la última y mejor versión estable del equipo de
|
<p>When not specified, Angular is assumed to be referring to the latest and greatest stable version from the Angular Team.</p>
|
||||||
Angular. </p>
|
|
||||||
<h4>Ejemplo</h4>
|
|
||||||
<p><b> Versión v4.1 ya disponible </b>: Nos complace anunciar que la última versión de Angular ya está
|
|
||||||
disponible. ¡Mantenerse actualizado es fácil! </p>
|
|
||||||
|
|
||||||
<h4>Ejemplo</h4>
|
<h4>Example</h4>
|
||||||
|
<p><b>Version v4.1 now available</b> - We are pleased to announce that the latest release of Angular is now available. Staying up to date is easy!</p>
|
||||||
|
|
||||||
<p><b>Correcto: </b> "Nuevo <code>*ngIf</code> capacidades</b>—nuevo en la versión 4.0 es la capacidad de
|
<h4>Example</h4>
|
||||||
..."</p>
|
|
||||||
<p><b style="color: red">Incorrecto: </b> "Nuevo <code>*ngIf</code> capacidades en Angular 4</b>—Angular 4
|
|
||||||
introduce la capacidad de ..."</p>
|
|
||||||
|
|
||||||
<p><b>Razonamiento</b></p>
|
<p><b>Correct: </b> "New <code>*ngIf</code> capabilities</b>—new in version 4.0 is the ability to ..."</p>
|
||||||
|
<p><b style="color: red">Incorrect: </b> "New <code>*ngIf</code> capabilities in Angular 4</b>—Angular 4 introduces the ability to ..."</p>
|
||||||
|
|
||||||
<p> Al no usar "Angular 4" en el título, el contenido aún se siente aplicable y útil después de que se hayan
|
<p><b>Reasoning</b></p>
|
||||||
lanzado las versiones 5, 6, 7, ya que es poco probable que la sintaxis cambie a corto y mediano plazo. </p>
|
|
||||||
|
<p>By not using “Angular 4” in the title, the content still feels applicable and useful after version 5, 6, 7 have been released, as the syntax is unlikely to change in the short and medium term.</p>
|
||||||
|
|
||||||
<h3>AngularJS</h3>
|
<h3>AngularJS</h3>
|
||||||
|
|
||||||
<p><b> AngularJS </b> es la serie v1.x de trabajo y promesas proporcionadas por el equipo de Angular. </p>
|
<p><b>AngularJS</b> is the v1.x series of work and promises provided by the Angular team.</p>
|
||||||
|
|
||||||
<h4>Ejemplos</h4>
|
<h4>Examples</h4>
|
||||||
<ol>
|
<ol>
|
||||||
<li> AngularJS es uno de los frameworks más utilizados en la web en la actualidad (por número de proyectos). </li>
|
<li>AngularJS is one of the most used framework on the web today (by number of projects).</li>
|
||||||
<li> Millones de desarrolladores están construyendo actualmente con AngularJS. </li>
|
<li>Millions of developers are currently building with AngularJS.</li>
|
||||||
<li> Los desarrolladores están comenzando a actualizar de AngularJS a Angular. </li>
|
<li>Developers are beginning to upgrade from AngularJS to Angular.</li>
|
||||||
<li> Estoy actualizando mi aplicación de AngularJS a Angular. </li>
|
<li>I’m upgrading my application from AngularJS to Angular.</li>
|
||||||
<li> Estoy usando AngularJS Material en este proyecto. </li>
|
<li>I'm using AngularJS Material on this project.</li>
|
||||||
</ol>
|
</ol>
|
||||||
|
|
||||||
<p>Los proyectos de AngularJS deben usar el
|
<p>AngularJS projects should use the
|
||||||
<a href="assets/images/logos/angularjs/AngularJS-Shield.svg" title="AngularJS logo">
|
<a href="assets/images/logos/angularjs/AngularJS-Shield.svg" title="AngularJS logo">
|
||||||
logo original de AngularJS </a> / icono, y no el icono de Angular.</p>
|
original AngularJS logo</a> / icon, and not the Angular icon.</p>
|
||||||
|
|
||||||
<img src="assets/images/logos/angularjs/AngularJS-Shield.svg" alt="AngularJS Logo" style="margin-left:20px;"
|
<img src="assets/images/logos/angularjs/AngularJS-Shield.svg" alt="AngularJS Logo" style="margin-left:20px;" height="128" width="128">
|
||||||
height="128" width="128">
|
|
||||||
|
|
||||||
<h3>Angular Material</h3>
|
<h3>Angular Material</h3>
|
||||||
|
|
||||||
<p>Este es el trabajo que está realizando el equipo de Angular para proporcionar componentes de Material Design
|
<p>This is the work being performed by the Angular team to provide Material Design components for Angular applications.</p>
|
||||||
para aplicaciones Angular.</p>
|
|
||||||
|
|
||||||
<h3>Material de AngularJS</h3>
|
<h3>AngularJS Material</h3>
|
||||||
|
|
||||||
<p>Este es el trabajo que está realizando el equipo de Angular en los componentes de Material Design que son
|
<p>This is the work being performed by the Angular team on Material Design components that are compatible with AngularJS.</p>
|
||||||
compatibles con AngularJS.</p>
|
|
||||||
|
|
||||||
<h3>Proyectos de terceros</h3>
|
<h3>3rd Party Projects</h3>
|
||||||
|
|
||||||
<p><b>X para Angular</b></p>
|
<p><b>X for Angular</b></p>
|
||||||
|
|
||||||
<p>Los terceros deben utilizar la terminología "X para Angular" o "ng-X" para proyectos de software. Los
|
<p>3rd parties should use the terminology “X for Angular” or “ng-X” for software projects. Projects should avoid the use of Angular X (e.g. Angular UI Toolkit), as it could create authorship confusion. This rule does not apply to events or meetup groups.</p>
|
||||||
proyectos deben evitar el uso de Angular X (por ejemplo, Angular UI Toolkit), ya que podría crear confusión en
|
|
||||||
la autoría. Esta regla no se aplica a eventos o grupos de reuniones.</p>
|
|
||||||
|
|
||||||
<p>Los desarrolladores deben evitar el uso de números de versión de Angular en los nombres de los proyectos, ya
|
<p>Developers should avoid using Angular version numbers in project names, as this will artificially limit their projects by tying them to a point in time of Angular, or will require renaming over time.</p>
|
||||||
que esto limitará artificialmente sus proyectos al vincularlos a un punto en el tiempo de Angular, o requerirá
|
|
||||||
un cambio de nombre con el tiempo.</p>
|
|
||||||
|
|
||||||
<p>Cuando se usa un nombre en clave o un nombre abreviado, como en npm o github, algunos son aceptables, otros
|
<p>Where a codename or shortname is used, such as on npm or github, some are acceptable, some are not acceptable.</p>
|
||||||
no.</p>
|
|
||||||
|
|
||||||
<b>No utilices</b>
|
<b>Do not use</b>
|
||||||
<ul>
|
<ul>
|
||||||
<li><code>ng2-</code></li>
|
<li><code>ng2-</code></li>
|
||||||
<li><code>angular2-</code></li>
|
<li><code>angular2-</code></li>
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
<b>Utiliza</b>
|
<b>OK to use</b>
|
||||||
<ul>
|
<ul>
|
||||||
<li><code>ng-</code></li>
|
<li><code>ng-</code></li>
|
||||||
<li><code>angular-</code></li>
|
<li><code>angular-</code></li>
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
<p>Como siempre, los selectores de componentes y directivas no deben comenzar con selectores "ng-", ya que esto
|
<p>As always, component and directive selectors should not begin with “ng-” selectors as this will conflict with components and directives provided by the Angular team.</p>
|
||||||
entrará en conflicto con los componentes y las directivas proporcionadas por el equipo de Angular.</p>
|
|
||||||
|
|
||||||
<h4>Ejemplos</h4>
|
<h4>Examples</h4>
|
||||||
<ul>
|
<ul>
|
||||||
<li>El equipo ng-BE acaba de lanzar <code>ng-health</code> Para ayudar a los desarrolladores a rastrear su
|
<li>The ng-BE team just launched <code>ng-health</code> to help developers track their own health.</li>
|
||||||
propia salud.</li>
|
<li>I’m going to use NativeScript for Angular to take advantage of native UI widgets.</li>
|
||||||
<li>Voy a usar NativeScript para Angular para aprovechar los widgets de IU nativos.</li>
|
<li><code>ReallyCoolTool</code> for Angular.</li>
|
||||||
<li><code>ReallyCoolTool</code> para Angular.</li>
|
<li><code>ReallyCoolTool</code> for AngularJS.</li>
|
||||||
<li><code>ReallyCoolTool</code> para AngularJS.</li>
|
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -682,10 +614,10 @@
|
|||||||
<div class="presskit-row">
|
<div class="presskit-row">
|
||||||
<div class="presskit-inner">
|
<div class="presskit-inner">
|
||||||
<div class="bullets">
|
<div class="bullets">
|
||||||
<h2>TÉRMINOS QUE UTILIZAMOS</h2>
|
<h2>TERMS WE USE</h2>
|
||||||
<p>
|
<p>
|
||||||
A menudo utilizamos términos que no forman parte de nuestra marca,
|
We often use terms that are not part of our brand,
|
||||||
pero queremos ser consistentes en el estilo y el uso de ellos para evitar confusiones y parecer unificados.
|
but we want to remain consistent on the styling and use of them to prevent confusion and to appear unified.
|
||||||
</p>
|
</p>
|
||||||
<ul>
|
<ul>
|
||||||
<li>Ahead of Time compilation (AOT)</li>
|
<li>Ahead of Time compilation (AOT)</li>
|
||||||
|
@ -1,37 +1,37 @@
|
|||||||
{
|
{
|
||||||
"Comunidad": {
|
"Community": {
|
||||||
"order": 3,
|
"order": 3,
|
||||||
"subCategories": {
|
"subCategories": {
|
||||||
"Elecciones de la comunidad": {
|
"Community Curations": {
|
||||||
"order": 1,
|
"order": 1,
|
||||||
"resources": {
|
"resources": {
|
||||||
"awesome-angular-components": {
|
"awesome-angular-components": {
|
||||||
"desc": "Un índice de componentes y librerías de la comunidad mantenido en GitHub",
|
"desc": "A community index of components and libraries maintained on GitHub",
|
||||||
"title": "Catálogo de librerías y componentes Angular",
|
"title": "Catalog of Angular Components & Libraries",
|
||||||
"url": "https://github.com/brillout/awesome-angular-components"
|
"url": "https://github.com/brillout/awesome-angular-components"
|
||||||
},
|
},
|
||||||
"angular-ru": {
|
"angular-ru": {
|
||||||
"desc": "La comunidad Angular-RU en GitHub es un punto de entrada único para todos los recursos, chats, podcasts y reuniones de Angular en Rusia.",
|
"desc": "Angular-RU Community on GitHub is a single entry point for all resources, chats, podcasts and meetups for Angular in Russia.",
|
||||||
"title": "Angular Conferences and Angular Camps in Moscow, Russia.",
|
"title": "Angular Conferences and Angular Camps in Moscow, Russia.",
|
||||||
"url": "https://angular-ru.github.io/"
|
"url": "https://angular-ru.github.io/"
|
||||||
},
|
},
|
||||||
"made-with-angular": {
|
"made-with-angular": {
|
||||||
"desc": "Una muestra de aplicaciones web creadas con Angular.",
|
"desc": "A showcase of web apps built with Angular.",
|
||||||
"title": "Hecho con Angular",
|
"title": "Made with Angular",
|
||||||
"url": "https://www.madewithangular.com/"
|
"url": "https://www.madewithangular.com/"
|
||||||
},
|
},
|
||||||
"angular-subreddit": {
|
"angular-subreddit": {
|
||||||
"desc": "Un subreddit dedicado a Angular.",
|
"desc": "An Angular-dedicated subreddit.",
|
||||||
"title": "Angular Subreddit",
|
"title": "Angular Subreddit",
|
||||||
"url": "https://www.reddit.com/r/Angular2/"
|
"url": "https://www.reddit.com/r/Angular2/"
|
||||||
},
|
},
|
||||||
"angular-devto": {
|
"angular-devto": {
|
||||||
"desc": "Lee, comparte contenido y chatea sobre Angular en la comunidad DEV.",
|
"desc": "Read and share content and chat about Angular on DEV Community.",
|
||||||
"url": "https://dev.to/t/angular",
|
"url": "https://dev.to/t/angular",
|
||||||
"title": "DEV Community"
|
"title": "DEV Community"
|
||||||
},
|
},
|
||||||
"angular-in-depth": {
|
"angular-in-depth": {
|
||||||
"desc": "El lugar donde se explican los conceptos de Angular avanzados",
|
"desc": "The place where advanced Angular concepts are explained",
|
||||||
"url": "https://blog.angularindepth.com",
|
"url": "https://blog.angularindepth.com",
|
||||||
"title": "Angular In Depth"
|
"title": "Angular In Depth"
|
||||||
}
|
}
|
||||||
@ -41,25 +41,25 @@
|
|||||||
"order": 3,
|
"order": 3,
|
||||||
"resources": {
|
"resources": {
|
||||||
"sdfjkdkfj": {
|
"sdfjkdkfj": {
|
||||||
"desc": "Adventures in Angular es un podcast semanal dedicado a la plataforma Angular y tecnologías relacionadas, herramientas, lenguajes y prácticas.",
|
"desc": "Adventures in Angular is a weekly podcast dedicated to the Angular platform and related technologies, tools, languages, and practices.",
|
||||||
"logo": "",
|
"logo": "",
|
||||||
"title": "Adventures in Angular",
|
"title": "Adventures in Angular",
|
||||||
"url": "https://devchat.tv/adv-in-angular/"
|
"url": "https://devchat.tv/adv-in-angular/"
|
||||||
},
|
},
|
||||||
"sdlkfjsldfkj": {
|
"sdlkfjsldfkj": {
|
||||||
"desc": "Podcast de video semanal presentado por Jeff Whelpley con los últimos y más grandes acontecimientos en el salvaje mundo de Angular.",
|
"desc": "Weekly video podcast hosted by Jeff Whelpley with all the latest and greatest happenings in the wild world of Angular.",
|
||||||
"logo": "",
|
"logo": "",
|
||||||
"title": "AngularAir",
|
"title": "AngularAir",
|
||||||
"url": "https://angularair.com/"
|
"url": "https://angularair.com/"
|
||||||
},
|
},
|
||||||
"sdlkfjsldfkz": {
|
"sdlkfjsldfkz": {
|
||||||
"desc": "Un podcast alemán semanal para Angular muy activo.",
|
"desc": "A weekly German podcast for Angular on the go",
|
||||||
"logo": "",
|
"logo": "",
|
||||||
"title": "Podcast de Happy Angular",
|
"title": "Happy Angular Podcast",
|
||||||
"url": "https://happy-angular.de/"
|
"url": "https://happy-angular.de/"
|
||||||
},
|
},
|
||||||
"ngruair": {
|
"ngruair": {
|
||||||
"desc": "Podcast de video en ruso sobre Angular.",
|
"desc": "Russian language video podcast about Angular.",
|
||||||
"logo": "",
|
"logo": "",
|
||||||
"title": "NgRuAir",
|
"title": "NgRuAir",
|
||||||
"url": "https://github.com/ngRuAir/ngruair"
|
"url": "https://github.com/ngRuAir/ngruair"
|
||||||
@ -68,75 +68,80 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"Desarrollo": {
|
"Development": {
|
||||||
"order": 1,
|
"order": 1,
|
||||||
"subCategories": {
|
"subCategories": {
|
||||||
"Desarrollo multiplataforma": {
|
"Cross-Platform Development": {
|
||||||
"order": 5,
|
"order": 5,
|
||||||
"resources": {
|
"resources": {
|
||||||
"a3b": {
|
"a3b": {
|
||||||
"desc": "Ionic ofrece una biblioteca de componentes y herramientas HTML, CSS y JS optimizados para dispositivos móviles para crear aplicaciones web nativas y progresivas altamente interactivas.",
|
"desc": "Ionic offers a library of mobile-optimized HTML, CSS and JS components and tools for building highly interactive native and progressive web apps.",
|
||||||
"logo": "http://ionicframework.com/img/ionic-logo-white.svg",
|
"logo": "http://ionicframework.com/img/ionic-logo-white.svg",
|
||||||
"title": "Ionic",
|
"title": "Ionic",
|
||||||
"url": "https://ionicframework.com/docs"
|
"url": "https://ionicframework.com/docs"
|
||||||
},
|
},
|
||||||
"a4b": {
|
"a4b": {
|
||||||
"desc": "Plataforma de Electron para Angular.",
|
"desc": "Electron Platform for Angular.",
|
||||||
"logo": "",
|
"logo": "",
|
||||||
"title": "Electron",
|
"title": "Electron",
|
||||||
"url": "https://github.com/maximegris/angular-electron"
|
"url": "https://github.com/maximegris/angular-electron"
|
||||||
},
|
},
|
||||||
"ab": {
|
"ab": {
|
||||||
"desc": "NativeScript es la forma de crear aplicaciones nativas de iOS y Android multiplataforma con Angular y TypeScript. Obtenga acceso al 100% a las API nativas a través de JavaScript y reutilice paquetes de NPM, CocoaPods y Gradle. Código abierto y respaldado por Telerik.",
|
"desc": "NativeScript is how you build cross-platform, native iOS and Android apps with Angular and TypeScript. Get 100% access to native APIs via JavaScript and reuse of packages from NPM, CocoaPods and Gradle. Open source and backed by Telerik.",
|
||||||
"logo": "",
|
"logo": "",
|
||||||
"title": "NativeScript",
|
"title": "NativeScript",
|
||||||
"url": "https://docs.nativescript.org/angular/start/introduction"
|
"url": "https://docs.nativescript.org/angular/start/introduction"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"Librerías de datos": {
|
"Data Libraries": {
|
||||||
"order": 3,
|
"order": 3,
|
||||||
"resources": {
|
"resources": {
|
||||||
|
"formly": {
|
||||||
|
"desc": "Formly is a dynamic (JSON powered) form library, built on top of Angular Reactive Forms.",
|
||||||
|
"title": "Formly",
|
||||||
|
"url": "https://formly.dev"
|
||||||
|
},
|
||||||
"rx-web": {
|
"rx-web": {
|
||||||
"desc": "RxWeb Reactive Form Validators proporciona todo tipo de validación compleja, condicional, de campo cruzado y dinámica en formularios reactivos basados en validadores, formularios reactivos basados en modelos y formularios controlados por plantillas.",
|
"desc": "RxWeb Reactive Form Validators provides all types of complex, conditional, cross field, and dynamic validation on validator-based reactive forms, model-based reactive forms, and template driven forms.",
|
||||||
"title": "Validadores de formularios reactivos RxWeb",
|
"title": "RxWeb Reactive Form Validators",
|
||||||
"url": "https://www.rxweb.io"
|
"url": "https://www.rxweb.io"
|
||||||
},
|
},
|
||||||
"-KLIzHDRfiB3d7W7vk-e": {
|
"-KLIzHDRfiB3d7W7vk-e": {
|
||||||
"desc": "Extensiones reactivas para Angular",
|
"desc": "Reactive Extensions for Angular",
|
||||||
"title": "ngrx",
|
"title": "ngrx",
|
||||||
"url": "https://ngrx.io/"
|
"url": "https://ngrx.io/"
|
||||||
},
|
},
|
||||||
"ngxs": {
|
"ngxs": {
|
||||||
"desc": "NGXS es un patrón de gestión de estado + librería para Angular. NGXS se basa en el patrón CRS implementado popularmente en librerías como Redux y NgRx, pero reduce el texto estándar mediante el uso de características modernas de TypeScript, como clases y decoradores.",
|
"desc": "NGXS is a state management pattern + library for Angular. NGXS is modeled after the CQRS pattern popularly implemented in libraries like Redux and NgRx but reduces boilerplate by using modern TypeScript features such as classes and decorators.",
|
||||||
"title": "NGXS",
|
"title": "NGXS",
|
||||||
"url": "https://ngxs.io/"
|
"url": "https://ngxs.io/"
|
||||||
},
|
},
|
||||||
"akita": {
|
"akita": {
|
||||||
"desc": "Akita es un patrón de administración de estado, construido sobre RxJS, que toma la idea de múltiples almacenes de datos de Flux y las actualizaciones inmutables de Redux, junto con el concepto de transmisión de datos, para crear el modelo Observable Data Store.",
|
"desc": "Akita is a state management pattern, built on top of RxJS, which takes the idea of multiple data stores from Flux and the immutable updates from Redux, along with the concept of streaming data, to create the Observable Data Store model.",
|
||||||
"title": "Akita",
|
"title": "Akita",
|
||||||
"url": "https://netbasal.gitbook.io/akita/"
|
"url": "https://netbasal.gitbook.io/akita/"
|
||||||
},
|
},
|
||||||
"ab": {
|
"ab": {
|
||||||
"desc": "La biblioteca oficial de Firebase y Angular",
|
"desc": "The official library for Firebase and Angular",
|
||||||
"logo": "",
|
"logo": "",
|
||||||
"title": "Angular Fire",
|
"title": "Angular Fire",
|
||||||
"url": "https://github.com/angular/angularfire"
|
"url": "https://github.com/angular/angularfire2"
|
||||||
},
|
},
|
||||||
"ab2": {
|
"ab2": {
|
||||||
"desc": "Utilice Angular y Meteor para crear aplicaciones JavaScript de pila completa para dispositivos móviles y de escritorio.",
|
"desc": "Use Angular and Meteor to build full-stack JavaScript apps for Mobile and Desktop.",
|
||||||
"logo": "http://www.angular-meteor.com/images/logo.png",
|
"logo": "http://www.angular-meteor.com/images/logo.png",
|
||||||
"title": "Meteor",
|
"title": "Meteor",
|
||||||
"url": "https://github.com/urigo/angular-meteor"
|
"url": "https://github.com/urigo/angular-meteor"
|
||||||
},
|
},
|
||||||
"ab3": {
|
"ab3": {
|
||||||
"desc": "Apollo es una pila de datos para aplicaciones modernas, construida con GraphQL.",
|
"desc": "Apollo is a data stack for modern apps, built with GraphQL.",
|
||||||
"logo": "http://docs.apollostack.com/logo/large.png",
|
"logo": "http://docs.apollostack.com/logo/large.png",
|
||||||
"title": "Apollo",
|
"title": "Apollo",
|
||||||
"url": "https://www.apollographql.com/docs/angular/"
|
"url": "https://www.apollographql.com/docs/angular/"
|
||||||
},
|
},
|
||||||
"ngx-api-utils": {
|
"ngx-api-utils": {
|
||||||
"desc": "ngx-api-utils es una biblioteca ajustada de utilidades y ayudantes para integrar rápidamente cualquier API HTTP (REST, Ajax y cualquier otra) con Angular.",
|
"desc": "ngx-api-utils is a lean library of utilities and helpers to quickly integrate any HTTP API (REST, Ajax, and any other) with Angular.",
|
||||||
"logo": "",
|
"logo": "",
|
||||||
"title": "ngx-api-utils",
|
"title": "ngx-api-utils",
|
||||||
"url": "https://github.com/ngx-api-utils/ngx-api-utils"
|
"url": "https://github.com/ngx-api-utils/ngx-api-utils"
|
||||||
@ -147,274 +152,281 @@
|
|||||||
"order": 1,
|
"order": 1,
|
||||||
"resources": {
|
"resources": {
|
||||||
"ab": {
|
"ab": {
|
||||||
"desc": "VS Code es una herramienta ligera y gratuita para editar y depurar aplicaciones web.",
|
"desc": "VS Code is a Free, Lightweight Tool for Editing and Debugging Web Apps.",
|
||||||
"logo": "",
|
"logo": "",
|
||||||
"title": "Visual Studio Code",
|
"title": "Visual Studio Code",
|
||||||
"url": "http://code.visualstudio.com/"
|
"url": "http://code.visualstudio.com/"
|
||||||
},
|
},
|
||||||
"ab2": {
|
"ab2": {
|
||||||
"desc": "IDE ligero pero potente, perfectamente equipado para el desarrollo complejo del lado del cliente y el desarrollo del lado del servidor con Node.js",
|
"desc": "Lightweight yet powerful IDE, perfectly equipped for complex client-side development and server-side development with Node.js",
|
||||||
"logo": "",
|
"logo": "",
|
||||||
"title": "WebStorm",
|
"title": "WebStorm",
|
||||||
"url": "https://www.jetbrains.com/webstorm/"
|
"url": "https://www.jetbrains.com/webstorm/"
|
||||||
},
|
},
|
||||||
"ab3": {
|
"ab3": {
|
||||||
"desc": "Java capaz y ergonómico * IDE",
|
"desc": "Capable and Ergonomic Java * IDE",
|
||||||
"logo": "",
|
"logo": "",
|
||||||
"title": "IntelliJ IDEA",
|
"title": "IntelliJ IDEA",
|
||||||
"url": "https://www.jetbrains.com/idea/"
|
"url": "https://www.jetbrains.com/idea/"
|
||||||
},
|
},
|
||||||
"angular-ide": {
|
"angular-ide": {
|
||||||
"desc": "Construido ante todo para Angular. Configuración llave en mano para principiantes; poderoso para expertos.",
|
"desc": "Built first and foremost for Angular. Turnkey setup for beginners; powerful for experts.",
|
||||||
"title": "Angular IDE by Webclipse",
|
"title": "Angular IDE by Webclipse",
|
||||||
"url": "https://www.genuitec.com/products/angular-ide"
|
"url": "https://www.genuitec.com/products/angular-ide"
|
||||||
},
|
},
|
||||||
"amexio-canvas": {
|
"amexio-canvas": {
|
||||||
"desc": "Amexio Canvas es un entorno de arrastrar y soltar para crear aplicaciones web y de dispositivos inteligentes HTML5 / Angular totalmente sensibles El código se generará automáticamente y se implementará en caliente mediante Canvas para realizar pruebas en vivo. Soporte listo para usar 50+ Temas de Diseño Material. Confirme su código en el repositorio público o privado de GitHub.",
|
"desc": "Amexio Canvas is Drag and Drop Environment to create Fully Responsive Web and Smart Device HTML5/Angular Apps. Code will be auto generated and hot deployed by the Canvas for live testing. Out of the box 50+ Material Design Theme support. Commit your code to GitHub public or private repository.",
|
||||||
"title": "Amexio Canvas Web Based Drag and Drop IDE by MetaMagic",
|
"title": "Amexio Canvas Web Based Drag and Drop IDE by MetaMagic",
|
||||||
"url": "https://amexio.tech/"
|
"url": "https://amexio.tech/"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"Montaje": {
|
"Tooling": {
|
||||||
"order": 2,
|
"order": 2,
|
||||||
"resources": {
|
"resources": {
|
||||||
"a1": {
|
"a1": {
|
||||||
"desc": "Una extensión de Google Chrome Dev Tools para depurar aplicaciones angular.",
|
"desc": "A Google Chrome Dev Tools extension for debugging Angular applications.",
|
||||||
"logo": "https://augury.angular.io/images/augury-logo.svg",
|
"logo": "https://augury.angular.io/images/augury-logo.svg",
|
||||||
"title": "Augury",
|
"title": "Augury",
|
||||||
"url": "http://augury.angular.io/"
|
"url": "http://augury.angular.io/"
|
||||||
},
|
},
|
||||||
"b1": {
|
"b1": {
|
||||||
"desc": "Representación del lado del servidor para aplicaciones Angular.",
|
"desc": "Server-side Rendering for Angular apps.",
|
||||||
"logo": "https://cloud.githubusercontent.com/assets/1016365/10639063/138338bc-7806-11e5-8057-d34c75f3cafc.png",
|
"logo": "https://cloud.githubusercontent.com/assets/1016365/10639063/138338bc-7806-11e5-8057-d34c75f3cafc.png",
|
||||||
"title": "Angular Universal",
|
"title": "Angular Universal",
|
||||||
"url": "https://angular.io/guide/universal"
|
"url": "https://angular.io/guide/universal"
|
||||||
},
|
},
|
||||||
"c1": {
|
"c1": {
|
||||||
"desc": "Servidor Node.js® de desarrollo ligero",
|
"desc": "Lightweight development only Node.js® server",
|
||||||
"logo": "",
|
"logo": "",
|
||||||
"title": "Lite-server",
|
"title": "Lite-server",
|
||||||
"url": "https://github.com/johnpapa/lite-server"
|
"url": "https://github.com/johnpapa/lite-server"
|
||||||
},
|
},
|
||||||
"cli": {
|
"cli": {
|
||||||
"desc": "La CLI oficial de Angular facilita la creación y el desarrollo de aplicaciones desde el compromiso inicial hasta la implementación de producción. ¡Ya sigue nuestras mejores prácticas desde el primer momento!",
|
"desc": "The official Angular CLI makes it easy to create and develop applications from initial commit to production deployment. It already follows our best practices right out of the box!",
|
||||||
"title": "Angular CLI",
|
"title": "Angular CLI",
|
||||||
"url": "https://cli.angular.io"
|
"url": "https://cli.angular.io"
|
||||||
},
|
},
|
||||||
"d1": {
|
"d1": {
|
||||||
"desc": "Análisis estático para proyectos Angular.",
|
"desc": "Static analysis for Angular projects.",
|
||||||
"logo": "",
|
"logo": "",
|
||||||
"title": "Codelyzer",
|
"title": "Codelyzer",
|
||||||
"url": "https://github.com/mgechev/codelyzer"
|
"url": "https://github.com/mgechev/codelyzer"
|
||||||
},
|
},
|
||||||
"f1": {
|
"f1": {
|
||||||
"desc": "Esta herramienta genera documentación dedicada para aplicaciones Angular.",
|
"desc": "This tool generates dedicated documentation for Angular applications.",
|
||||||
"logo": "",
|
"logo": "",
|
||||||
"title": "Compodoc",
|
"title": "Compodoc",
|
||||||
"url": "https://github.com/compodoc/compodoc"
|
"url": "https://github.com/compodoc/compodoc"
|
||||||
},
|
},
|
||||||
"angular-playground": {
|
"angular-playground": {
|
||||||
"desc": "Entorno de desarrollo de la interfaz de usuario para crear, probar y documentar aplicaciones Angular.",
|
"desc": "UI development environment for building, testing, and documenting Angular applications.",
|
||||||
"title": "Patio de juegos Angular",
|
"title": "Angular Playground",
|
||||||
"url": "http://www.angularplayground.it/"
|
"url": "http://www.angularplayground.it/"
|
||||||
},
|
},
|
||||||
"nx": {
|
"nx": {
|
||||||
"desc": "Nx (Nrwl Extensions for Angular) es un kit de herramientas de código abierto construido sobre Angular CLI para ayudar a los equipos empresariales a desarrollar Angular a escala.",
|
"desc": "Nx (Nrwl Extensions for Angular) is an open source toolkit built on top of Angular CLI to help enterprise teams develop Angular at scale.",
|
||||||
"title": "Nx",
|
"title": "Nx",
|
||||||
"logo": "https://nrwl.io/assets/nx-logo.png",
|
"logo": "https://nrwl.io/assets/nx-logo.png",
|
||||||
"url": "https://nrwl.io/nx"
|
"url": "https://nrwl.io/nx"
|
||||||
},
|
},
|
||||||
"uijar": {
|
"uijar": {
|
||||||
"desc": "Un módulo desplegable para crear automáticamente una guía de estilo viva basada en la prueba que escribe para sus componentes.",
|
"desc": "A drop in module to automatically create a living style guide based on the test you write for your components.",
|
||||||
"logo": "",
|
"logo": "",
|
||||||
"title": "UI-jar: desarrollo de guías de estilo basado en pruebas",
|
"title": "UI-jar - Test Driven Style Guide Development",
|
||||||
"url": "https://github.com/ui-jar/ui-jar"
|
"url": "https://github.com/ui-jar/ui-jar"
|
||||||
},
|
},
|
||||||
"protactor": {
|
"protactor": {
|
||||||
"desc": "El marco oficial de prueba de extremo a extremo para aplicaciones Angular",
|
"desc": "The official end to end testing framework for Angular apps",
|
||||||
"logo": "",
|
"logo": "",
|
||||||
"title": "Protractor",
|
"title": "Protractor",
|
||||||
"url": "https://protractor.angular.io/"
|
"url": "https://protractor.angular.io/"
|
||||||
|
},
|
||||||
|
"scully": {
|
||||||
|
"desc": "Scully (Jamstack Toolchain for Angular) makes building, testing, and deploying Jamstack apps extremely simple.",
|
||||||
|
"title": "Scully",
|
||||||
|
"logo": "https://raw.githubusercontent.com/scullyio/scully/main/assets/logos/PNG/Green/scullyio-logo-green.png",
|
||||||
|
"url": "https://scully.io"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"Componentes UI": {
|
"UI Components": {
|
||||||
"order": 4,
|
"order": 4,
|
||||||
"resources": {
|
"resources": {
|
||||||
"AngularUIToolkit": {
|
"AngularUIToolkit": {
|
||||||
"desc": "Kit de herramientas de interfaz de usuario angular: 115 componentes de interfaz de usuario mantenidos profesionalmente que van desde una cuadrícula robusta hasta gráficos y más. Pruébelo gratis y cree aplicaciones Angular más rápido.",
|
"desc": "Angular UI Toolkit: 115 professionally maintained UI components ranging from a robust grid to charts and more. Try for free & build Angular apps faster.",
|
||||||
"title": "Kit de herramientas Angular UI",
|
"title": "Angular UI Toolkit",
|
||||||
"url": "https://www.angular-ui-tools.com"
|
"url": "https://www.angular-ui-tools.com"
|
||||||
},
|
},
|
||||||
"SenchaforAngular": {
|
"SenchaforAngular": {
|
||||||
"desc": "Cree aplicaciones web modernas más rápido con más de 115 UI Componentes prediseñados. Pruébelo gratis y descárguelo hoy.",
|
"desc": "Build modern web apps faster with 115+ pre-built UI components. Try for free and download today.",
|
||||||
"title": "Sencha para Angular",
|
"title": "Sencha for Angular",
|
||||||
"url": "https://www.sencha.com/products/extangular/"
|
"url": "https://www.sencha.com/products/extangular/"
|
||||||
},
|
},
|
||||||
"IgniteUIforAngular": {
|
"IgniteUIforAngular": {
|
||||||
"desc": "Ignite UI para Angular es un kit de herramientas Angular sin dependencia para crear aplicaciones web modernas.",
|
"desc": "Ignite UI for Angular is a dependency-free Angular toolkit for building modern web apps.",
|
||||||
"title": "Ignite UI para Angular",
|
"title": "Ignite UI for Angular",
|
||||||
"url": "https://www.infragistics.com/products/ignite-ui-angular?utm_source=angular.io&utm_medium=Referral&utm_campaign=Angular"
|
"url": "https://www.infragistics.com/products/ignite-ui-angular?utm_source=angular.io&utm_medium=Referral&utm_campaign=Angular"
|
||||||
},
|
},
|
||||||
"DevExtreme": {
|
"DevExtreme": {
|
||||||
"desc": "Más de 50 componentes UI que incluyen cuadrícula de datos, cuadrícula dinámica, programador, gráficos, editores, mapas y otros controles multipropósito para crear aplicaciones web altamente receptivas para dispositivos táctiles y escritorios tradicionales.",
|
"desc": "50+ UI components including data grid, pivot grid, scheduler, charts, editors, maps and other multi-purpose controls for creating highly responsive web applications for touch devices and traditional desktops.",
|
||||||
"title": "DevExtreme",
|
"title": "DevExtreme",
|
||||||
"url": "https://js.devexpress.com/Overview/Angular/"
|
"url": "https://js.devexpress.com/Overview/Angular/"
|
||||||
},
|
},
|
||||||
"234237": {
|
"234237": {
|
||||||
"desc": "Las pautas de UX, el marco HTML / CSS y los componentes Angular trabajan juntos para crear experiencias excepcionales",
|
"desc": "UX guidelines, HTML/CSS framework, and Angular components working together to craft exceptional experiences",
|
||||||
"title": "Sistema de diseño de Clarity",
|
"title": "Clarity Design System",
|
||||||
"url": "https://vmware.github.io/clarity/"
|
"url": "https://vmware.github.io/clarity/"
|
||||||
},
|
},
|
||||||
"-KMVB8P4TDfht8c0L1AE": {
|
"-KMVB8P4TDfht8c0L1AE": {
|
||||||
"desc": "La versión de Angular de la biblioteca Bootstrap de Angular UI. Esta biblioteca se está construyendo desde cero en Typescript utilizando el marco CSS Bootstrap 4.",
|
"desc": "The Angular version of the Angular UI Bootstrap library. This library is being built from scratch in Typescript using the Bootstrap 4 CSS framework.",
|
||||||
"title": "ng-bootstrap",
|
"title": "ng-bootstrap",
|
||||||
"url": "https://ng-bootstrap.github.io/"
|
"url": "https://ng-bootstrap.github.io/"
|
||||||
},
|
},
|
||||||
"4ab": {
|
"4ab": {
|
||||||
"desc": "Directivas y componentes Angular nativos para Lightning Design System",
|
"desc": "Native Angular components & directives for Lightning Design System",
|
||||||
"logo": "http://ng-lightning.github.io/ng-lightning/img/shield.svg",
|
"logo": "http://ng-lightning.github.io/ng-lightning/img/shield.svg",
|
||||||
"title": "ng-lightning",
|
"title": "ng-lightning",
|
||||||
"url": "http://ng-lightning.github.io/ng-lightning/"
|
"url": "http://ng-lightning.github.io/ng-lightning/"
|
||||||
},
|
},
|
||||||
"7ab": {
|
"7ab": {
|
||||||
"desc": "Componentes UI para aplicaciones móviles híbridas con enlaces para Angular y AngularJS.",
|
"desc": "UI components for hybrid mobile apps with bindings for both Angular & AngularJS.",
|
||||||
"title": "Onsen UI",
|
"title": "Onsen UI",
|
||||||
"url": "https://onsen.io/v2/"
|
"url": "https://onsen.io/v2/"
|
||||||
},
|
},
|
||||||
"a2b": {
|
"a2b": {
|
||||||
"desc": "PrimeNG es una colección rica de componentes UI para Angular",
|
"desc": "PrimeNG is a collection of rich UI components for Angular",
|
||||||
"logo": "http://www.primefaces.org/primeng/showcase/resources/images/primeng.svg",
|
"logo": "http://www.primefaces.org/primeng/showcase/resources/images/primeng.svg",
|
||||||
"title": "Prime Faces",
|
"title": "Prime Faces",
|
||||||
"url": "http://www.primefaces.org/primeng/"
|
"url": "http://www.primefaces.org/primeng/"
|
||||||
},
|
},
|
||||||
"a3b": {
|
"a3b": {
|
||||||
"desc": "Una biblioteca de grado profesional de los Componentes UI de Angular escrita en TypeScript que incluye nuestro Data Grid, TreeView, Charts, Editors, DropDowns, DatePickers y muchos más. Las características incluyen soporte para la compilación AOT, Tree Shaking para alto rendimiento, localización y accesibilidad.",
|
"desc": "A professional grade library of Angular UI components written in TypeScript that includes our Data Grid, TreeView, Charts, Editors, DropDowns, DatePickers, and many more. Features include support for AOT compilation, Tree Shaking for high-performance, localization, and accessibility.",
|
||||||
"logo": "",
|
"logo": "",
|
||||||
"title": "Kendo UI",
|
"title": "Kendo UI",
|
||||||
"url": "http://www.telerik.com/kendo-angular-ui/"
|
"url": "http://www.telerik.com/kendo-angular-ui/"
|
||||||
},
|
},
|
||||||
"a5b": {
|
"a5b": {
|
||||||
"desc": "Controles UI de Alto-Rendimiento con el soporte más completo para Angular. Wijmo’s controla todo lo que esta escrito en TypeScript y no tiene ninguna dependecia. El control FlexGrid incluye marcado declarativo completo, incluyendo plantillas de celda.",
|
"desc": "High-performance UI controls with the most complete Angular support available. Wijmo’s controls are all written in TypeScript and have zero dependencies. FlexGrid control includes full declarative markup, including cell templates.",
|
||||||
"logo": "http://wijmocdn.azureedge.net/wijmositeblob/wijmo-theme/logos/wijmo-55.png",
|
"logo": "http://wijmocdn.azureedge.net/wijmositeblob/wijmo-theme/logos/wijmo-55.png",
|
||||||
"title": "Wijmo",
|
"title": "Wijmo",
|
||||||
"url": "http://wijmo.com/products/wijmo-5/"
|
"url": "http://wijmo.com/products/wijmo-5/"
|
||||||
},
|
},
|
||||||
"a6b": {
|
"a6b": {
|
||||||
"desc": "El diseño de materiales inspiró la interfaz de usuario de Componentes para crear excelentes aplicaciones web. Para dispositivos móviles y de escritorio.",
|
"desc": "Material design inspired UI components for building great web apps. For mobile and desktop.",
|
||||||
"logo": "",
|
"logo": "",
|
||||||
"title": "Vaadin",
|
"title": "Vaadin",
|
||||||
"url": "https://vaadin.com/elements"
|
"url": "https://vaadin.com/elements"
|
||||||
},
|
},
|
||||||
"a7b": {
|
"a7b": {
|
||||||
"desc": "Directivas Angular nativas para Bootstrap",
|
"desc": "Native Angular directives for Bootstrap",
|
||||||
"logo": "",
|
"logo": "",
|
||||||
"title": "ngx-bootstrap",
|
"title": "ngx-bootstrap",
|
||||||
"url": "http://valor-software.com/ngx-bootstrap/#/"
|
"url": "http://valor-software.com/ngx-bootstrap/#/"
|
||||||
},
|
},
|
||||||
"ab": {
|
"ab": {
|
||||||
"desc": "Componentes de Material Design para Angular",
|
"desc": "Material Design components for Angular",
|
||||||
"logo": "",
|
"logo": "",
|
||||||
"title": "Angular Material",
|
"title": "Angular Material",
|
||||||
"url": "https://material.angular.io/"
|
"url": "https://material.angular.io/"
|
||||||
},
|
},
|
||||||
"mcc": {
|
"mcc": {
|
||||||
"desc": "Componentes Material fabricados por la comunidad",
|
"desc": "Material components made by the community",
|
||||||
"logo": "",
|
"logo": "",
|
||||||
"title": "Material Community Components",
|
"title": "Material Community Components",
|
||||||
"url": "https://github.com/tiaguinho/material-community-components"
|
"url": "https://github.com/tiaguinho/material-community-components"
|
||||||
},
|
},
|
||||||
"mosaic": {
|
"mosaic": {
|
||||||
"desc": "Positive Technologies Componentes UI basada en Angular",
|
"desc": "Positive Technologies UI components based on Angular",
|
||||||
"logo": "https://i.ibb.co/fQNPgv6/logo-png-200.png",
|
"logo": "https://i.ibb.co/fQNPgv6/logo-png-200.png",
|
||||||
"title": "Mosaic - Angular Componentes UI",
|
"title": "Mosaic - Angular UI Components",
|
||||||
"url": "https://github.com/positive-js/mosaic"
|
"url": "https://github.com/positive-js/mosaic"
|
||||||
},
|
},
|
||||||
"ngzorro": {
|
"ngzorro": {
|
||||||
"desc": "Un conjunto de UI de Componentes de clase empresarial basada en Ant Design y Angular",
|
"desc": "A set of enterprise-class UI components based on Ant Design and Angular",
|
||||||
"title": "Ant Design de Angular (ng-zorro-antd)",
|
"title": "Ant Design of Angular (ng-zorro-antd)",
|
||||||
"url": "https://ng.ant.design/docs/introduce/en"
|
"url": "https://ng.ant.design/docs/introduce/en"
|
||||||
},
|
},
|
||||||
"ngzorromobile": {
|
"ngzorromobile": {
|
||||||
"title": "Ant Design Mobile de Angular (ng-zorro-antd-mobile)",
|
"desc": "A set of enterprise-class mobile UI components based on Ant Design Mobile and Angular",
|
||||||
|
"title": "Ant Design Mobile of Angular (ng-zorro-antd-mobile)",
|
||||||
"url": "http://ng.mobile.ant.design/#/docs/introduce/en"
|
"url": "http://ng.mobile.ant.design/#/docs/introduce/en"
|
||||||
},
|
},
|
||||||
"aggrid": {
|
"aggrid": {
|
||||||
"desc": "Una cuadrícula de datos para Angular con características de estilo empresarial como clasificación, filtrado, renderizado personalizado, edición, agrupación, agregación y pivotación.",
|
"desc": "A datagrid for Angular with enterprise style features such as sorting, filtering, custom rendering, editing, grouping, aggregation and pivoting.",
|
||||||
"title": "ag-Grid",
|
"title": "ag-Grid",
|
||||||
"url": "https://www.ag-grid.com/best-angular-2-data-grid/"
|
"url": "https://www.ag-grid.com/best-angular-2-data-grid/"
|
||||||
},
|
},
|
||||||
"angular-slickgrid": {
|
"angular-slickgrid": {
|
||||||
"desc": "Angular-SlickGrid es un contenedor de la biblioteca de cuadrículas de datos SlickGrid, ultrarrápida y personalizable, con temas de Bootstrap 3,4",
|
"desc": "Angular-SlickGrid is a wrapper of the lightning fast & customizable SlickGrid datagrid library with Bootstrap 3,4 themes",
|
||||||
"title": "Angular-Slickgrid",
|
"title": "Angular-Slickgrid",
|
||||||
"url": "https://github.com/ghiscoding/Angular-Slickgrid"
|
"url": "https://github.com/ghiscoding/Angular-Slickgrid"
|
||||||
},
|
},
|
||||||
"fancygrid": {
|
"fancygrid": {
|
||||||
"desc": "Biblioteca de cuadrícula Angular con integración de gráficos y comunicación con el servidor para empresas.",
|
"desc": "Angular grid library with charts integration and server communication for Enterprise.",
|
||||||
"title": "FancyGrid",
|
"title": "FancyGrid",
|
||||||
"url": "https://fancygrid.com/docs/getting-started/angular"
|
"url": "https://fancygrid.com/docs/getting-started/angular"
|
||||||
},
|
},
|
||||||
"ngx-smart-modal": {
|
"ngx-smart-modal": {
|
||||||
"desc": "Controlador modal Angular inteligente, ligero y rápido para administrar modales y datos en todas partes.",
|
"desc": "Angular smart, light and fast modal handler to manage modals and data everywhere.",
|
||||||
"title": "ngx-smart-modal",
|
"title": "ngx-smart-modal",
|
||||||
"url": "https://biig-io.github.io/ngx-smart-modal"
|
"url": "https://biig-io.github.io/ngx-smart-modal"
|
||||||
},
|
},
|
||||||
"jqwidgets": {
|
"jqwidgets": {
|
||||||
"desc": "Interfaz de usuario de Angular Componentes que incluye cuadrícula de datos, cuadrícula de árbol, cuadrícula dinámica, programador, gráficos, editores y otros componentes multipropósito",
|
"desc": "Angular UI Components including data grid, tree grid, pivot grid, scheduler, charts, editors and other multi-purpose components",
|
||||||
"title": "jQWidgets",
|
"title": "jQWidgets",
|
||||||
"url": "https://www.jqwidgets.com/angular/"
|
"url": "https://www.jqwidgets.com/angular/"
|
||||||
},
|
},
|
||||||
"amexio": {
|
"amexio": {
|
||||||
"desc": "Amexio es un extenso conjunto de componentes Angular impulsados por HTML5 y CSS3 para diseño web receptivo y más de 80 temas de diseño de materiales integrados. Amexio tiene 3 ediciones, Standard, Enterprise y Creative. Std Edition consta de una interfaz de usuario básica de Componentes que incluye cuadrícula, pestañas, entradas de formulario, etc. Mientras que Enterprise Edition consta de componentes como Calendario, pestañas de árbol, inicios de sesión en redes sociales (Facebook, GitHub, Twitter, etc.) y Creative Edition se centra en la construcción de sitios web elegantes y hermosos. Con más de 200 componentes/características. Todas las ediciones son de código abierto y gratuitas, basadas en la licencia Apache 2.",
|
"desc": "Amexio is a rich set of Angular components powered by HTML5 & CSS3 for Responsive Web Design and 80+ built-in Material Design Themes. Amexio has 3 Editions, Standard, Enterprise and Creative. Std Edition consists of basic UI Components which include Grid, Tabs, Form Inputs and so on. While Enterprise Edition consists of components like Calendar, Tree Tabs, Social Media Logins (Facebook, GitHub, Twitter and so on) and Creative Edition is focused building elegant and beautiful websites. With more than 200+ components/features. All the editions are open-sourced and free, based on Apache 2 License.",
|
||||||
"title": "Amexio - Extensiones Angular",
|
"title": "Amexio - Angular Extensions",
|
||||||
"url": "http://www.amexio.tech/",
|
"url": "http://www.amexio.tech/",
|
||||||
"logo": "http://www.amexio.org/amexio-logo.png"
|
"logo": "http://www.amexio.org/amexio-logo.png"
|
||||||
},
|
},
|
||||||
"bm": {
|
"bm": {
|
||||||
"desc": "Una biblioteca ligera de diseño de materiales para Angular, basada en los componentes de materiales de Google para la Web",
|
"desc": "A lightweight Material Design library for Angular, based upon Google's Material Components for the Web",
|
||||||
"logo": "https://blox.src.zone/assets/bloxmaterial.03ecfe4fa0147a781487749dc1cc4580.svg",
|
"logo": "https://blox.src.zone/assets/bloxmaterial.03ecfe4fa0147a781487749dc1cc4580.svg",
|
||||||
"title": "Blox Material",
|
"title": "Blox Material",
|
||||||
"url": "https://github.com/src-zone/material"
|
"url": "https://github.com/src-zone/material"
|
||||||
},
|
},
|
||||||
"essentialjs2": {
|
"essentialjs2": {
|
||||||
"desc": "Essential JS 2 para Angular es una colección de componentes Angular verdaderos basados en TypeScript modernos. Tiene soporte para la compilación Ahead Of Time (AOT) y Tree-Shaking. Todos los componentes se desarrollan desde cero para ser livianos, receptivos, modulares y fáciles de tocar.",
|
"desc": "Essential JS 2 for Angular is a collection modern TypeScript based true Angular Components. It has support for Ahead Of Time (AOT) compilation and Tree-Shaking. All the components are developed from the ground up to be lightweight, responsive, modular and touch friendly.",
|
||||||
"title": "Essential JS 2",
|
"title": "Essential JS 2",
|
||||||
"url": "https://www.syncfusion.com/products/angular-js2"
|
"url": "https://www.syncfusion.com/products/angular-js2"
|
||||||
},
|
},
|
||||||
"trulyui": {
|
"trulyui": {
|
||||||
"desc": "TrulyUI es un marco de interfaz de usuario Angular especialmente desarrollado para aplicaciones de escritorio basadas en componentes web que utilizan las mejores tecnologías del mundo.",
|
"desc": "TrulyUI is an Angular UI Framework especially developed for Desktop Applications based on Web Components using the greatest technologies of the world.",
|
||||||
"title": "Truly UI",
|
"title": "Truly UI",
|
||||||
"url": "http://truly-ui.com"
|
"url": "http://truly-ui.com"
|
||||||
},
|
},
|
||||||
"ngsqui": {
|
"ngsqui": {
|
||||||
"desc": "La interfaz de usuario de calidad simple (SQ-UI) es un kit de interfaz de usuario flexible y fácilmente personalizable, cuyo objetivo es proporcionar la máxima eficiencia con la menor sobrecarga posible. Impulsado por la idea de que debería ser estrictamente \" para desarrolladores por desarrolladores \", cada lanzamiento de nuevas funciones incluye funcionalidades exigidas por los desarrolladores que lo utilizan.",
|
"desc": "Simple Quality UI (SQ-UI) is a flexible and easily customizable UI-kit, aiming to provide maximum efficiency with as little overhead as possible. Driven by the idea that it should be strictly \"for developers by developers\", every new feature release includes functionalities demanded by the developers who are using it.",
|
||||||
"logo": "https://sq-ui.github.io/ng-sq-ui/_media/sq-ui-logo.png",
|
"logo": "https://sq-ui.github.io/ng-sq-ui/_media/sq-ui-logo.png",
|
||||||
"title": "Simple Quality UI",
|
"title": "Simple Quality UI",
|
||||||
"url": "https://sq-ui.github.io/ng-sq-ui/#/"
|
"url": "https://sq-ui.github.io/ng-sq-ui/#/"
|
||||||
},
|
},
|
||||||
"smart": {
|
"smart": {
|
||||||
"desc": "Componentes web para Angular. Componentes Angular sin dependencias para crear aplicaciones web modernas y aptas para dispositivos móviles",
|
"desc": "Web Components for Angular. Dependency-free Angular components for building modern and mobile-friendly web apps",
|
||||||
"title": "Componentes web inteligentes",
|
"title": "Smart Web Components",
|
||||||
"url": "https://www.htmlelements.com/angular/"
|
"url": "https://www.htmlelements.com/angular/"
|
||||||
},
|
},
|
||||||
"AlyleUI": {
|
"AlyleUI": {
|
||||||
"desc": "Minimal Design, un conjunto de componentes para Angular.",
|
"desc": "Minimal Design, a set of components for Angular.",
|
||||||
"title": "Alyle UI",
|
"title": "Alyle UI",
|
||||||
"url": "https://alyle-ui.firebaseapp.com/"
|
"url": "https://alyle-ui.firebaseapp.com/"
|
||||||
},
|
},
|
||||||
"nebular": {
|
"nebular": {
|
||||||
"desc": "Theme System, Componentes UI, Autenticación y seguridad para su próxima aplicación Angular.",
|
"desc": "Theme System, UI Components, Auth and Security for your next Angular application.",
|
||||||
"title": "Nebular",
|
"title": "Nebular",
|
||||||
"url": "https://akveo.github.io/nebular/"
|
"url": "https://akveo.github.io/nebular/"
|
||||||
},
|
},
|
||||||
"carbondesignsystem": {
|
"carbondesignsystem": {
|
||||||
"desc": "Una implementación Angular del Carbon Design System para IBM.",
|
"desc": "An Angular implementation of the Carbon Design System for IBM.",
|
||||||
"title": "Carbon Components Angular",
|
"title": "Carbon Components Angular",
|
||||||
"url": "https://angular.carbondesignsystem.com/"
|
"url": "https://angular.carbondesignsystem.com/"
|
||||||
},
|
},
|
||||||
"jigsaw": {
|
"jigsaw": {
|
||||||
"desc": "Jigsaw proporciona un conjunto de componentes web basados en Angular. Está apoyando el desarrollo de todas las aplicaciones de Big Data Producto de ZTE (https://www.zte.com.cn).",
|
"desc": "Jigsaw provides a set of web components based on Angular. It is supporting the development of all applications of Big Data Product of ZTE (https://www.zte.com.cn).",
|
||||||
"title": "Awade Jigsaw (Chinese)",
|
"title": "Awade Jigsaw (Chinese)",
|
||||||
"url": "https://jigsaw-zte.gitee.io"
|
"url": "https://jigsaw-zte.gitee.io"
|
||||||
}
|
}
|
||||||
@ -422,296 +434,295 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"Educación": {
|
"Education": {
|
||||||
"order": 2,
|
"order": 2,
|
||||||
"subCategories": {
|
"subCategories": {
|
||||||
"Libros": {
|
"Books": {
|
||||||
"order": 1,
|
"order": 1,
|
||||||
"resources": {
|
"resources": {
|
||||||
"-KLIzGEp8Mh5W-FkiQnL": {
|
"-KLIzGEp8Mh5W-FkiQnL": {
|
||||||
"desc": "Tu guía rápida y sensata para crear aplicaciones del mundo real con Angular",
|
"desc": "Your quick, no-nonsense guide to building real-world apps with Angular",
|
||||||
"title": "Aprendiendo Angular - Segunda edición",
|
"title": "Learning Angular - Second Edition",
|
||||||
"url": "https://www.packtpub.com/web-development/learning-angular-second-edition"
|
"url": "https://www.packtpub.com/web-development/learning-angular-second-edition"
|
||||||
},
|
},
|
||||||
"3ab": {
|
"3ab": {
|
||||||
"desc": "Más de 15 libros de O'Reilly sobre Angular",
|
"desc": "More than 15 books from O'Reilly about Angular",
|
||||||
"title": "Medios de comunicación O'Reilly",
|
"title": "O'Reilly Media",
|
||||||
"url": "https://ssearch.oreilly.com/?q=angular"
|
"url": "https://ssearch.oreilly.com/?q=angular"
|
||||||
},
|
},
|
||||||
"a5b": {
|
"a5b": {
|
||||||
"desc": "El libro en profundidad, completo y actualizado sobre Angular. Conviértete en un experto en Angular hoy.",
|
"desc": "The in-depth, complete, and up-to-date book on Angular. Become an Angular expert today.",
|
||||||
"title": "ng-book",
|
"title": "ng-book",
|
||||||
"url": "https://www.ng-book.com/2/"
|
"url": "https://www.ng-book.com/2/"
|
||||||
},
|
},
|
||||||
"a7b": {
|
"a7b": {
|
||||||
"desc": "Este libro electrónico te ayudará a comprender la filosofía del marco: qué proviene de 1.x, qué se ha introducido y por qué",
|
"desc": "This ebook will help you getting the philosophy of the framework: what comes from 1.x, what has been introduced and why",
|
||||||
"title": "Convertirse en un ninja con Angular",
|
"title": "Becoming a Ninja with Angular",
|
||||||
"url": "https://books.ninja-squad.com/angular"
|
"url": "https://books.ninja-squad.com/angular"
|
||||||
},
|
},
|
||||||
"ab": {
|
"ab": {
|
||||||
"desc": "Más de 10 libros de Packt Publicados sobre Angular",
|
"desc": "More than 10 books from Packt Publishing about Angular",
|
||||||
"title": "Packt Publishing",
|
"title": "Packt Publishing",
|
||||||
"url": "https://www.packtpub.com/catalogsearch/result/?q=angular"
|
"url": "https://www.packtpub.com/catalogsearch/result/?q=angular"
|
||||||
},
|
},
|
||||||
"cnoring-rxjs-fundamentals": {
|
"cnoring-rxjs-fundamentals": {
|
||||||
"desc": "Un libro gratuito que cubre todas las facetas del trabajo con Rxjs, desde tu primer Observable hasta cómo hacer que tu código se ejecute a una velocidad óptima con Schedulers.",
|
"desc": "A free book that covers all facets of working with Rxjs from your first Observable to how to make your code run at optimal speed with Schedulers.",
|
||||||
"title": "RxJS Ultimate",
|
"title": "RxJS Ultimate",
|
||||||
"url": "https://chrisnoring.gitbooks.io/rxjs-5-ultimate/content/"
|
"url": "https://chrisnoring.gitbooks.io/rxjs-5-ultimate/content/"
|
||||||
},
|
},
|
||||||
"vsavkin-angular-router": {
|
"vsavkin-angular-router": {
|
||||||
"desc": "Este libro es una guía completa del enrutador Angular escrita por su diseñador. El libro explora la biblioteca en profundidad, incluido el modelo mental, las limitaciones de diseño y las sutilezas de la API.",
|
"desc": "This book is a comprehensive guide to the Angular router written by its designer. The book explores the library in depth, including the mental model, design constraints, subtleties of the API.",
|
||||||
"title": "Angular Router",
|
"title": "Angular Router",
|
||||||
"url": "https://leanpub.com/router"
|
"url": "https://leanpub.com/router"
|
||||||
},
|
},
|
||||||
"vsavkin-essential-angular": {
|
"vsavkin-essential-angular": {
|
||||||
"desc": "El libro es una descripción breve, pero al mismo tiempo bastante completa, de los aspectos clave de Angular escrita por sus colaboradores principales, Victor Savkin y Jeff Cross. El libro te dará una base sólida. Te ayudará a poner todos los conceptos en los lugares correctos. De este modo, comprenderás bien por qué el marco es como es.",
|
"desc": "The book is a short, but at the same time, fairly complete overview of the key aspects of Angular written by its core contributors Victor Savkin and Jeff Cross. The book will give you a strong foundation. It will help you put all the concepts into right places. So you will get a good understanding of why the framework is the way it is.",
|
||||||
"title": "Angular Esencial",
|
"title": "Essential Angular",
|
||||||
"url": "https://gumroad.com/l/essential_angular"
|
"url": "https://gumroad.com/l/essential_angular"
|
||||||
},
|
},
|
||||||
"angular-buch": {
|
"angular-buch": {
|
||||||
"desc": "El primer libro alemán sobre Angular. Te brinda una descripción práctica detallada de los conceptos clave de la plataforma. En cada capítulo se crea una aplicación de muestra con un nuevo tema de Angular. Todas las fuentes están disponibles en GitHub.",
|
"desc": "The first German book about Angular. It gives you a detailed practical overview of the key concepts of the platform. In each chapter a sample application is built upon with a new Angular topic. All sources are available on GitHub.",
|
||||||
"logo": "https://angular-buch.com/assets/img/brand.svg",
|
"logo": "https://angular-buch.com/assets/img/brand.svg",
|
||||||
"title": "Angular-Buch (Alemán)",
|
"title": "Angular-Buch (German)",
|
||||||
"url": "https://angular-buch.com/"
|
"url": "https://angular-buch.com/"
|
||||||
},
|
},
|
||||||
"wishtack-guide-angular": {
|
"wishtack-guide-angular": {
|
||||||
"desc": "La guía de Angular gratuita, de código abierto y actualizada. Esta guía pragmática se centra en las mejores prácticas y lo llevará de cero a la nube.",
|
"desc": "The free, open-source and up-to-date Angular guide. This pragmatic guide is focused on best practices and will drive you from scratch to cloud.",
|
||||||
"logo": "https://raw.githubusercontent.com/wishtack/gitbook-guide-angular/master/.gitbook/assets/wishtack-logo-with-text.png",
|
"logo": "https://raw.githubusercontent.com/wishtack/gitbook-guide-angular/master/.gitbook/assets/wishtack-logo-with-text.png",
|
||||||
"title": "La guía de Angular de Wishtack (Francés)",
|
"title": "The Angular Guide by Wishtack (Français)",
|
||||||
"url": "https://guide-angular.wishtack.io/"
|
"url": "https://guide-angular.wishtack.io/"
|
||||||
},
|
},
|
||||||
"ab5": {
|
"ab5": {
|
||||||
"desc": "Cómo construir aplicaciones Angular usando NGRX",
|
"desc": "How to build Angular applications using NGRX",
|
||||||
"logo": "",
|
"logo": "",
|
||||||
"title": "Arquitectura de aplicaciones Angular con NGRX",
|
"title": "Architecting Angular Applications with NGRX",
|
||||||
"url": "https://www.packtpub.com/web-development/architecting-angular-applications-redux"
|
"url": "https://www.packtpub.com/web-development/architecting-angular-applications-redux"
|
||||||
},
|
},
|
||||||
"dwa": {
|
"dwa": {
|
||||||
"desc": "Viaje práctico con Angular framework, ES6, TypeScript, webpack y Angular CLI.",
|
"desc": "Practical journey with Angular framework, ES6, TypeScript, webpack and Angular CLI.",
|
||||||
"title": "Desarrollando con Angular",
|
"title": "Developing with Angular",
|
||||||
"url": "https://leanpub.com/developing-with-angular"
|
"url": "https://leanpub.com/developing-with-angular"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"Entrenamiento en linea": {
|
"Online Training": {
|
||||||
"order": 3,
|
"order": 3,
|
||||||
"resources": {
|
"resources": {
|
||||||
"angular-dyma": {
|
"angular-dyma": {
|
||||||
"desc": "Aprende Angular y todo su ecosistema (Material, Flex-layout, Ngrx y más) desde cero.",
|
"desc": "Learn Angular and all its ecosystem (Material, Flex-layout, Ngrx and more) from scratch.",
|
||||||
"title": "Dyma (francés)",
|
"title": "Dyma (French)",
|
||||||
"url": "https://dyma.fr/angular"
|
"url": "https://dyma.fr/angular"
|
||||||
},
|
},
|
||||||
"-KLIBoTWXMiBcvG0dAM6": {
|
"-KLIBoTWXMiBcvG0dAM6": {
|
||||||
"desc": "Este curso le presenta los conceptos básicos de este marco \"superheroico\", incluidas las plantillas declarativas, el enlace de datos bidireccional y la inyección de dependencias.",
|
"desc": "This course introduces you to the essentials of this \"superheroic\" framework, including declarative templates, two-way data binding, and dependency injection.",
|
||||||
"title": "Angular: entrenamiento esencial",
|
"title": "Angular: Essential Training",
|
||||||
"url": "https://www.lynda.com/AngularJS-tutorials/Angular-2-Essential-Training/540347-2.html"
|
"url": "https://www.lynda.com/AngularJS-tutorials/Angular-2-Essential-Training/540347-2.html"
|
||||||
},
|
},
|
||||||
"-KLIzGq3CiFeoZUemVyE": {
|
"-KLIzGq3CiFeoZUemVyE": {
|
||||||
"desc": "Aprenda los conceptos básicos, juegue con el código, conviértase en un desarrollador Angular competente",
|
"desc": "Learn the core concepts, play with the code, become a competent Angular developer",
|
||||||
"title": "Conceptos Angular, código y sabiduría colectiva",
|
"title": "Angular Concepts, Code and Collective Wisdom",
|
||||||
"url": "https://www.udemy.com/angular-2-concepts-code-and-collective-wisdom/"
|
"url": "https://www.udemy.com/angular-2-concepts-code-and-collective-wisdom/"
|
||||||
},
|
},
|
||||||
"-KLIzHwg-glQLXni1hvL": {
|
"-KLIzHwg-glQLXni1hvL": {
|
||||||
"desc": "Artículos e información de Angular en español",
|
"desc": "Spanish language Angular articles and information",
|
||||||
"title": "Academia Binaria (español)",
|
"title": "Academia Binaria (español)",
|
||||||
"url": "http://academia-binaria.com/"
|
"url": "http://academia-binaria.com/"
|
||||||
},
|
},
|
||||||
"-KN3uNQvxifu26D6WKJW": {
|
"-KN3uNQvxifu26D6WKJW": {
|
||||||
"category": "Educación",
|
"category": "Education",
|
||||||
"desc": "Cree el futuro de las aplicaciones web probando Angular.",
|
"desc": "Create the future of web applications by taking Angular for a test drive.",
|
||||||
"subcategory": "Entrenamiento en linea",
|
"subcategory": "Online Training",
|
||||||
"title": "CodeSchool: Acelerando a través de Angular",
|
"title": "CodeSchool: Accelerating Through Angular",
|
||||||
"url": "https://www.codeschool.com/courses/accelerating-through-angular-2"
|
"url": "https://www.codeschool.com/courses/accelerating-through-angular-2"
|
||||||
},
|
},
|
||||||
"angular-playbook": {
|
"angular-playbook": {
|
||||||
"desc": "Aprenda las mejores prácticas avanzadas de Angular para equipos empresariales, creadas por Nrwl.io.",
|
"desc": "Learn advanced Angular best practices for enterprise teams, created by Nrwl.io.",
|
||||||
"logo": "https://nrwl.io/assets/logo_footer_2x.png",
|
"logo": "https://nrwl.io/assets/logo_footer_2x.png",
|
||||||
"title": "Libro de estrategias de Angular Enterprise",
|
"title": "Angular Enterprise Playbook",
|
||||||
"url": "https://angularplaybook.com"
|
"url": "https://angularplaybook.com"
|
||||||
},
|
},
|
||||||
"a2b": {
|
"a2b": {
|
||||||
"desc": "Cientos de cursos Angular para todos los niveles",
|
"desc": "Hundreds of Angular courses for all skill levels",
|
||||||
"logo": "",
|
"logo": "",
|
||||||
"title": "Pluralsight",
|
"title": "Pluralsight",
|
||||||
"url": "https://www.pluralsight.com/paths/angular"
|
"url": "https://www.pluralsight.com/paths/angular"
|
||||||
},
|
},
|
||||||
"ab3": {
|
"ab3": {
|
||||||
"desc": "Cursos de Angular alojados por Udemy",
|
"desc": "Angular courses hosted by Udemy",
|
||||||
"logo": "",
|
"logo": "",
|
||||||
"title": "Udemy",
|
"title": "Udemy",
|
||||||
"url": "https://www.udemy.com/courses/search/?q=angular"
|
"url": "https://www.udemy.com/courses/search/?q=angular"
|
||||||
},
|
},
|
||||||
"ab4": {
|
"ab4": {
|
||||||
"desc": "Fundamentos de Angular y temas avanzados enfocados en Aplicaciones Angular de Estilo Redux",
|
"desc": "Angular Fundamentals and advanced topics focused on Redux Style Angular Applications",
|
||||||
"logo": "",
|
"logo": "",
|
||||||
"title": "Egghead.io",
|
"title": "Egghead.io",
|
||||||
"url": "https://egghead.io/browse/frameworks/angular"
|
"url": "https://egghead.io/browse/frameworks/angular"
|
||||||
},
|
},
|
||||||
"ab5": {
|
"ab5": {
|
||||||
"desc": "Cree aplicaciones web con Angular: contenido de video grabado",
|
"desc": "Build Web Apps with Angular - recorded video content",
|
||||||
"logo": "",
|
"logo": "",
|
||||||
"title": "Frontend Masters",
|
"title": "Frontend Masters",
|
||||||
"url": "https://frontendmasters.com/courses/angular-core/"
|
"url": "https://frontendmasters.com/courses/angular-core/"
|
||||||
},
|
},
|
||||||
"angular-love": {
|
"angular-love": {
|
||||||
"desc": "Artículos e información de Angular en polaco",
|
"desc": "Polish language Angular articles and information",
|
||||||
"title": "angular.love (Polaco)",
|
"title": "angular.love (Polski)",
|
||||||
"url": "http://www.angular.love/"
|
"url": "http://www.angular.love/"
|
||||||
},
|
},
|
||||||
"learn-angular-fr": {
|
"learn-angular-fr": {
|
||||||
|
"desc": "French language Angular content.",
|
||||||
"desc": "Contenido de Angular en Lengua francesa.",
|
"title": "Learn Angular (francais)",
|
||||||
"title": "Aprende Angular (francés)",
|
|
||||||
"url": "http://www.learn-angular.fr/"
|
"url": "http://www.learn-angular.fr/"
|
||||||
},
|
},
|
||||||
"upgrading-ajs": {
|
"upgrading-ajs": {
|
||||||
"desc": "El curso paso a paso más completo del mundo sobre el uso de las mejores prácticas y cómo evitar errores al migrar de AngularJS a Angular.",
|
"desc": "The world's most comprehensive, step-by-step course on using best practices and avoiding pitfalls while migrating from AngularJS to Angular.",
|
||||||
"title": "Actualización AngularJS",
|
"title": "Upgrading AngularJS",
|
||||||
"url": "https://www.upgradingangularjs.com"
|
"url": "https://www.upgradingangularjs.com"
|
||||||
},
|
},
|
||||||
"toddmotto-ultimateangular": {
|
"toddmotto-ultimateangular": {
|
||||||
"desc": "Cursos en línea que brindan una cobertura en profundidad del ecosistema Angular, AngularJS, Angular y TypeScript, con muestras de código funcional y un entorno de semillas con todas las funciones. Obtenga una comprensión profunda de Angular y TypeScript desde la base hasta la aplicación funcional, luego pase a temas avanzados con Todd Motto y sus colaboradores.",
|
"desc": "Online courses providing in-depth coverage of the Angular ecosystem, AngularJS, Angular and TypeScript, with functional code samples and a full-featured seed environment. Get a deep understanding of Angular and TypeScript from foundation to functional application, then move on to advanced topics with Todd Motto and collaborators.",
|
||||||
"title": "Ultimate Angular",
|
"title": "Ultimate Angular",
|
||||||
"url": "https://ultimateangular.com/"
|
"url": "https://ultimateangular.com/"
|
||||||
},
|
},
|
||||||
"willh-angular-zero": {
|
"willh-angular-zero": {
|
||||||
"desc": "Video curso en línea en chino para principiantes que necesitan aprender en chino desde cero. Cubre Angular, Angular CLI, TypeScript, VSCode, y algunos deben tener conocimiento del desarrollo Angular.",
|
"desc": "Online video course in Chinese for newbies who need to learning from the scratch in Chinese. It's covering Angular, Angular CLI, TypeScript, VSCode, and some must known knowledge of Angular development.",
|
||||||
"title": "Angular en acción: empezar desde cero (正體中文)",
|
"title": "Angular in Action: Start From Scratch (正體中文)",
|
||||||
"url": "https://www.udemy.com/angular-zero/?couponCode=ANGULAR.IO"
|
"url": "https://www.udemy.com/angular-zero/?couponCode=ANGULAR.IO"
|
||||||
},
|
},
|
||||||
"angular-firebase": {
|
"angular-firebase": {
|
||||||
"desc": "Lecciones en video que cubren aplicaciones web progresivas con Angular, Firebase, RxJS y API relacionadas.",
|
"desc": "Video lessons covering progressive web apps with Angular, Firebase, RxJS, and related APIs.",
|
||||||
"title": "AngularFirebase.com",
|
"title": "AngularFirebase.com",
|
||||||
"url": "https://angularfirebase.com/"
|
"url": "https://angularfirebase.com/"
|
||||||
},
|
},
|
||||||
"loiane-angulartraining": {
|
"loiane-angulartraining": {
|
||||||
"desc": "Curso gratuito de Angular en portugués.",
|
"desc": "Free Angular course in Portuguese.",
|
||||||
"title": "Loiane Training (Portugués)",
|
"title": "Loiane Training (Português)",
|
||||||
"url": "https://loiane.training/course/angular/"
|
"url": "https://loiane.training/course/angular/"
|
||||||
},
|
},
|
||||||
"web-dev-angular": {
|
"web-dev-angular": {
|
||||||
"desc": "Cree aplicaciones Angular progresivas y de alto rendimiento.",
|
"desc": "Build performant and progressive Angular applications.",
|
||||||
"title": "web.dev/angular",
|
"title": "web.dev/angular",
|
||||||
"url": "https://web.dev/angular"
|
"url": "https://web.dev/angular"
|
||||||
},
|
},
|
||||||
"mdb-angular-boilerplate": {
|
"mdb-angular-boilerplate": {
|
||||||
"desc": "Iniciador de aplicaciones Angular CRUD con administración de estado NgRx, backend de Firebase y guía de instalación.",
|
"desc": "Angular CRUD application starter with NgRx state management, Firebase backend and installation guide.",
|
||||||
"title": "MDB Angular Boilerplate",
|
"title": "MDB Angular Boilerplate",
|
||||||
"url": "https://github.com/mdbootstrap/Angular-Bootstrap-Boilerplate"
|
"url": "https://github.com/mdbootstrap/Angular-Bootstrap-Boilerplate"
|
||||||
},
|
},
|
||||||
"dotnettricks": {
|
"dotnettricks": {
|
||||||
"desc": "Vídeos online y formación para Angular.",
|
"desc": "Online videos and training for Angular.",
|
||||||
"logo": "",
|
"logo": "",
|
||||||
"title": "DotNetTricks",
|
"title": "DotNetTricks",
|
||||||
"url": "https://www.dotnettricks.com/courses/angular"
|
"url": "https://www.dotnettricks.com/courses/angular"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"Talleres y formación presencial": {
|
"Workshops & Onsite Training": {
|
||||||
"order": 2,
|
"order": 2,
|
||||||
"resources": {
|
"resources": {
|
||||||
"webucator": {
|
"webucator": {
|
||||||
"desc": "Capacitación en Angular personalizada en persona dirigida por un instructor para grupos privados y clases Angular públicas en línea dirigidas por un instructor.",
|
"desc": "Customized in-person instructor-led Angular training for private groups and public online instructor-led Angular classes.",
|
||||||
"title": "Webucator",
|
"title": "Webucator",
|
||||||
"url": "https://www.webucator.com/webdev-training/angular-training"
|
"url": "https://www.webucator.com/webdev-training/angular-training"
|
||||||
},
|
},
|
||||||
"-acceleb": {
|
"-acceleb": {
|
||||||
"desc": "Entrenamiento Angular personalizado y dirigido por un instructor",
|
"desc": "Customized, Instructor-Led Angular Training",
|
||||||
"title": "Accelebrate",
|
"title": "Accelebrate",
|
||||||
"url": "https://www.accelebrate.com/angular-training"
|
"url": "https://www.accelebrate.com/angular-training"
|
||||||
},
|
},
|
||||||
"-KLIBoFWStce29UCwkvY": {
|
"-KLIBoFWStce29UCwkvY": {
|
||||||
"desc": "Capacitación y tutoría privada de Angular",
|
"desc": "Private Angular Training and Mentoring",
|
||||||
"title": "Chariot Solutions",
|
"title": "Chariot Solutions",
|
||||||
"url": "http://chariotsolutions.com/course/angular2-workshop-fundamentals-architecture/"
|
"url": "http://chariotsolutions.com/course/angular2-workshop-fundamentals-architecture/"
|
||||||
},
|
},
|
||||||
"-KLIBoN0p9be3kwC6-ga": {
|
"-KLIBoN0p9be3kwC6-ga": {
|
||||||
"desc": "¡Angular Academy es un curso público práctico de dos días que se imparte en persona en todo Canadá!",
|
"desc": "Angular Academy is a two day hands-on public course given in-person across Canada!",
|
||||||
"title": "Angular Academy (Canada)",
|
"title": "Angular Academy (Canada)",
|
||||||
"url": "http://www.angularacademy.ca"
|
"url": "http://www.angularacademy.ca"
|
||||||
},
|
},
|
||||||
"at": {
|
"at": {
|
||||||
"desc": "Angular Training enseña Angular in situ en todo el mundo. También brinda consultoría y tutoría.",
|
"desc": "Angular Training teaches Angular on-site all over the world. Also provides consulting and mentoring.",
|
||||||
"title": "Angular Training",
|
"title": "Angular Training",
|
||||||
"url": "http://www.angulartraining.com"
|
"url": "http://www.angulartraining.com"
|
||||||
},
|
},
|
||||||
"-KLIBo_lm-WrK1Sjtt-2": {
|
"-KLIBo_lm-WrK1Sjtt-2": {
|
||||||
"desc": "Formación básica y avanzada en toda Europa en alemán",
|
"desc": "Basic and Advanced training across Europe in German",
|
||||||
"title": "TheCodeCampus (German)",
|
"title": "TheCodeCampus (German)",
|
||||||
"url": "https://www.thecodecampus.de/schulungen/angular"
|
"url": "https://www.thecodecampus.de/schulungen/angular"
|
||||||
},
|
},
|
||||||
"-KLIzFhfGKi1xttqJ7Uh": {
|
"-KLIzFhfGKi1xttqJ7Uh": {
|
||||||
"desc": "Formación en Angular en profundidad de 4 días en Israel",
|
"desc": "4 day in-depth Angular training in Israel",
|
||||||
"title": "ng-course (Israel)",
|
"title": "ng-course (Israel)",
|
||||||
"url": "http://ng-course.org/"
|
"url": "http://ng-course.org/"
|
||||||
},
|
},
|
||||||
"-KLIzIcRoDq3TzCJWnYc": {
|
"-KLIzIcRoDq3TzCJWnYc": {
|
||||||
"desc": "Capacitación virtual y presencial en Canadá y EE. UU.",
|
"desc": "Virtual and in-person training in Canada and the US",
|
||||||
"title": "Web Age Solutions",
|
"title": "Web Age Solutions",
|
||||||
"url": "http://www.webagesolutions.com/courses/WA2533-angular-2-programming"
|
"url": "http://www.webagesolutions.com/courses/WA2533-angular-2-programming"
|
||||||
},
|
},
|
||||||
"500tech": {
|
"500tech": {
|
||||||
"desc": "Aprenda de 500Tech, una consultora de Angular en Israel. Este curso fue creado por un desarrollador experto, que vive y respira Angular, y tiene experiencia práctica con aplicaciones Angular a gran escala del mundo real.",
|
"desc": "Learn from 500Tech, an Angular consultancy in Israel. This course was built by an expert developer, who lives and breathes Angular, and has practical experience with real world large scale Angular apps.",
|
||||||
"title": "Angular Hands-on Course (Israel)",
|
"title": "Angular Hands-on Course (Israel)",
|
||||||
"url": "http://angular2.courses.500tech.com/"
|
"url": "http://angular2.courses.500tech.com/"
|
||||||
},
|
},
|
||||||
"9ab": {
|
"9ab": {
|
||||||
"desc": "Capacitación en el sitio de los autores de \"Conviértete en un ninja con Angular\"",
|
"desc": "OnSite Training From the Authors of \"Become A Ninja with Angular\"",
|
||||||
"title": "Ninja Squad",
|
"title": "Ninja Squad",
|
||||||
"url": "http://ninja-squad.com/formations/formation-angular2"
|
"url": "http://ninja-squad.com/formations/formation-angular2"
|
||||||
},
|
},
|
||||||
"a2b": {
|
"a2b": {
|
||||||
"desc": "Angular Boot Camp cubre temas Angular desde la introducción hasta los avanzados. Incluye extensas sesiones de talleres, con la ayuda práctica de nuestros experimentados formadores-desarrolladores. Llevamos a los desarrolladores o equipos desde los inicios de la comprensión de Angular a través de un conocimiento práctico de todas las características esenciales de Angular.",
|
"desc": "Angular Boot Camp covers introductory through advanced Angular topics. It includes extensive workshop sessions, with hands-on help from our experienced developer-trainers. We take developers or teams from the beginnings of Angular understanding through a working knowledge of all essential Angular features.",
|
||||||
"logo": "https://angularbootcamp.com/images/angular-boot-camp-logo.svg",
|
"logo": "https://angularbootcamp.com/images/angular-boot-camp-logo.svg",
|
||||||
"title": "Angular Boot Camp",
|
"title": "Angular Boot Camp",
|
||||||
"url": "https://angularbootcamp.com"
|
"url": "https://angularbootcamp.com"
|
||||||
},
|
},
|
||||||
"ab3": {
|
"ab3": {
|
||||||
"desc": "Entrenamientos y revisiones de códigos. Ayudamos a las personas a obtener un conocimiento profundo de las diferentes tecnologías a través de capacitaciones y revisiones de código. Nuestros servicios se pueden organizar en línea, lo que hace posible unirse desde cualquier parte del mundo o en el sitio para obtener la mejor experiencia posible.",
|
"desc": "Trainings & Code Reviews. We help people to get a deep understanding of different technologies through trainings and code reviews. Our services can be arranged online, making it possible to join in from anywhere in the world, or on-site to get the best experience possible.",
|
||||||
"logo": "",
|
"logo": "",
|
||||||
"title": "Thoughtram",
|
"title": "Thoughtram",
|
||||||
"url": "http://thoughtram.io/"
|
"url": "http://thoughtram.io/"
|
||||||
},
|
},
|
||||||
"jsru": {
|
"jsru": {
|
||||||
"desc": "Curso completo en línea de Angular. Actualización constante. Seminarios web en tiempo real con comentarios inmediatos del profesor.",
|
"desc": "Complete Angular online course. Constantly updating. Real-time webinars with immediate feedback from the teacher.",
|
||||||
"logo": "https://learn.javascript.ru/img/sitetoolbar__logo_ru.svg",
|
"logo": "https://learn.javascript.ru/img/sitetoolbar__logo_ru.svg",
|
||||||
"title": "Learn Javascript (Russian)",
|
"title": "Learn Javascript (Russian)",
|
||||||
"url": "https://learn.javascript.ru/courses/angular"
|
"url": "https://learn.javascript.ru/courses/angular"
|
||||||
},
|
},
|
||||||
"zenika-angular": {
|
"zenika-angular": {
|
||||||
"desc": "Entrenamientos en Angular impartidos por Zenika (FRANCIA)",
|
"desc": "Angular trainings delivered by Zenika (FRANCE)",
|
||||||
"title": "Entrenamientos en Angular (francés)",
|
"title": "Angular Trainings (French)",
|
||||||
"url": "https://training.zenika.com/fr/training/angular/description"
|
"url": "https://training.zenika.com/fr/training/angular/description"
|
||||||
},
|
},
|
||||||
"formationjs": {
|
"formationjs": {
|
||||||
"desc": "Formación en Angular presencial en París (Francia). Talleres Angular mensuales y clases presenciales personalizadas. Estamos enfocados en Angular, por lo que siempre estamos al día.",
|
"desc": "Angular onsite training in Paris (France). Monthly Angular workshops and custom onsite classes. We are focused on Angular, so we are always up to date.",
|
||||||
"title": "Formation JavaScript (Frances)",
|
"title": "Formation JavaScript (French)",
|
||||||
"url": "https://formationjavascript.com/formation-angular/"
|
"url": "https://formationjavascript.com/formation-angular/"
|
||||||
},
|
},
|
||||||
"humancoders-angular": {
|
"humancoders-angular": {
|
||||||
"desc": "Entrenamientos en Angular impartidos por Human Coders (France)",
|
"desc": "Angular trainings delivered by Human Coders (France)",
|
||||||
"title": "Formation Angular (Frances)",
|
"title": "Formation Angular (French)",
|
||||||
"url": "https://www.humancoders.com/formations/angular"
|
"url": "https://www.humancoders.com/formations/angular"
|
||||||
},
|
},
|
||||||
"wao": {
|
"wao": {
|
||||||
"desc": "Formación en Angular impartida por We Are One Sàrl en Suiza",
|
"desc": "Onsite Angular Training delivered by We Are One Sàrl in Switzerland",
|
||||||
"logo": "https://weareone.ch/wordpress/wao-content/uploads/2014/12/logo_200_2x.png",
|
"logo": "https://weareone.ch/wordpress/wao-content/uploads/2014/12/logo_200_2x.png",
|
||||||
"title": "We Are One Sàrl",
|
"title": "We Are One Sàrl",
|
||||||
"url": "https://weareone.ch/courses/angular/"
|
"url": "https://weareone.ch/courses/angular/"
|
||||||
},
|
},
|
||||||
"angular-schule": {
|
"angular-schule": {
|
||||||
"desc": "Talleres públicos y capacitación presencial de Angular en Alemania de los autores del libro German Angular. También publicamos regularmente artículos y videos en nuestro blog (en inglés y alemán).",
|
"desc": "Angular onsite training and public workshops in Germany from the authors of the German Angular book. We also regularly post articles and videos on our blog (in English and German language).",
|
||||||
"logo": "https://angular.schule/assets/img/brand.svg",
|
"logo": "https://angular.schule/assets/img/brand.svg",
|
||||||
"title": "Angular.Schule (German)",
|
"title": "Angular.Schule (German)",
|
||||||
"url": "https://angular.schule/"
|
"url": "https://angular.schule/"
|
||||||
},
|
},
|
||||||
"strbrw": {
|
"strbrw": {
|
||||||
"desc": "Entrenamientos en Angular y RxJS, Revisiones de Código y consultoría. Ayudamos a los ingenieros de software de todo el mundo a crear mejores aplicaciones web ...",
|
"desc": "Angular and RxJS trainings, Code Reviews and consultancy. We help software engineers all over the world to create better web-applications...",
|
||||||
"title": "StrongBrew",
|
"title": "StrongBrew",
|
||||||
"url": "https://strongbrew.io/"
|
"url": "https://strongbrew.io/"
|
||||||
},
|
},
|
||||||
"angular.de": {
|
"angular.de": {
|
||||||
"desc": "Capacitaciónes en Angular en el lugar impartida por la mayor comunidad en el área de habla alemana en Alemania, Austria y Suiza. También publicamos regularmente artículos y tutoriales en nuestro blog.",
|
"desc": "Onsite Angular Training delivered by the greatest community in the german speaking area in Germany, Austria and Switzerland. We also regularly post articles and tutorials on our blog.",
|
||||||
"logo": "https://angular.de/assets/img/angular-de-logo.svg",
|
"logo": "https://angular.de/assets/img/angular-de-logo.svg",
|
||||||
"title": "Angular.de (German)",
|
"title": "Angular.de (German)",
|
||||||
"url": "https://angular.de/"
|
"url": "https://angular.de/"
|
||||||
|
@ -1,375 +0,0 @@
|
|||||||
# Try it: Manage data
|
|
||||||
|
|
||||||
At the end of [In-app Navigation](start/start-routing "Try it: In-app Navigation"), the online store application has a product catalog with two views: a product list and product details.
|
|
||||||
Users can click on a product name from the list to see details in a new view, with a distinct URL, or route.
|
|
||||||
|
|
||||||
This page guides you through creating the shopping cart in three phases:
|
|
||||||
|
|
||||||
* Update the product details view to include a "Buy" button, which adds the current product to a list of products that a cart service manages.
|
|
||||||
* Add a cart component, which displays the items in the cart.
|
|
||||||
* Add a shipping component, which retrieves shipping prices for the items in the cart by using Angular's `HttpClient` to retrieve shipping data from a `.json` file.
|
|
||||||
|
|
||||||
{@a services}
|
|
||||||
## Services
|
|
||||||
|
|
||||||
Services are an integral part of Angular applications. In Angular, a service is an instance of a class that you can make available to any part of your application using Angular's [dependency injection system](guide/glossary#dependency-injection "Dependency injection definition").
|
|
||||||
|
|
||||||
Services are the place where you share data between parts of your application. For the online store, the cart service is where you store your cart data and methods.
|
|
||||||
|
|
||||||
{@a create-cart-service}
|
|
||||||
## Create the shopping cart service
|
|
||||||
|
|
||||||
Up to this point, users can view product information, and
|
|
||||||
simulate sharing and being notified about product changes.
|
|
||||||
They cannot, however, buy products.
|
|
||||||
|
|
||||||
In this section, you add a "Buy" button to the product
|
|
||||||
details view and set up a cart service to store information
|
|
||||||
about products in the cart.
|
|
||||||
|
|
||||||
<div class="alert is-helpful">
|
|
||||||
|
|
||||||
A later part of this tutorial, [Use forms for user input](start/start-forms "Try it: Forms for user input"), guides you through accessing this cart service from the view where the user checks out.
|
|
||||||
|
|
||||||
</div>
|
|
||||||
|
|
||||||
{@a generate-cart-service}
|
|
||||||
### Define a cart service
|
|
||||||
|
|
||||||
1. To generate a cart service, right click on the `app` folder, choose `Angular Generator`, and choose `Service`. Name the new service `cart`.
|
|
||||||
|
|
||||||
<code-example header="src/app/cart.service.ts" path="getting-started/src/app/cart.service.1.ts"></code-example>
|
|
||||||
|
|
||||||
<div class="alert is-helpful>
|
|
||||||
|
|
||||||
The StackBlitz generator might provide the cart service in `app.module.ts` by default. That differs from the example, which uses a bundle-optimization technique, an `@Injectable()` decorator with the `{ providedIn: 'root' }` statement.
|
|
||||||
For more information about services, see [Introduction to Services and Dependency Injection](guide/architecture-services "Concepts > Intro to Services and DI").
|
|
||||||
|
|
||||||
</div>
|
|
||||||
|
|
||||||
1. In the `CartService` class, define an `items` property to store the array of the current products in the cart.
|
|
||||||
|
|
||||||
<code-example path="getting-started/src/app/cart.service.ts" header="src/app/cart.service.ts" region="props"></code-example>
|
|
||||||
|
|
||||||
1. Define methods to add items to the cart, return cart items, and clear the cart items:
|
|
||||||
|
|
||||||
<code-example path="getting-started/src/app/cart.service.ts" header="src/app/cart.service.ts" region="methods"></code-example>
|
|
||||||
|
|
||||||
* The `addToCart()` method appends a product to an array of `items`.
|
|
||||||
|
|
||||||
* The `getItems()` method collects the items users add to the cart and returns each item with its associated quantity.
|
|
||||||
|
|
||||||
* The `clearCart()` method returns an empty array of items.
|
|
||||||
|
|
||||||
{@a product-details-use-cart-service}
|
|
||||||
### Use the cart service
|
|
||||||
|
|
||||||
This section walks you through using the cart service to add a product to the cart with a "Buy" button.
|
|
||||||
|
|
||||||
1. Open `product-details.component.ts`.
|
|
||||||
|
|
||||||
1. Configure the component to use the cart service.
|
|
||||||
|
|
||||||
1. Import the cart service.
|
|
||||||
|
|
||||||
<code-example header="src/app/product-details/product-details.component.ts" path="getting-started/src/app/product-details/product-details.component.ts" region="cart-service">
|
|
||||||
</code-example>
|
|
||||||
|
|
||||||
1. Inject the cart service by adding it to the `constructor()`.
|
|
||||||
|
|
||||||
<code-example path="getting-started/src/app/product-details/product-details.component.ts" header="src/app/product-details/product-details.component.ts" region="inject-cart-service">
|
|
||||||
</code-example>
|
|
||||||
|
|
||||||
<!--
|
|
||||||
To do: Consider defining "inject" and describing the concept of "dependency injection"
|
|
||||||
-->
|
|
||||||
|
|
||||||
1. Define the `addToCart()` method, which adds the current product to the cart.
|
|
||||||
|
|
||||||
The `addToCart()` method does the following three things:
|
|
||||||
* Receives the current `product`.
|
|
||||||
* Uses the cart service's `addToCart()` method to add the product the cart.
|
|
||||||
* Displays a message that you've added a product to the cart.
|
|
||||||
|
|
||||||
<code-example path="getting-started/src/app/product-details/product-details.component.ts" header="src/app/product-details/product-details.component.ts" region="add-to-cart"></code-example>
|
|
||||||
|
|
||||||
1. Update the product details template with a "Buy" button that adds the current product to the cart.
|
|
||||||
|
|
||||||
1. Open `product-details.component.html`.
|
|
||||||
|
|
||||||
1. Add a button with the label "Buy", and bind the `click()` event to the `addToCart()` method:
|
|
||||||
|
|
||||||
<code-example header="src/app/product-details/product-details.component.html" path="getting-started/src/app/product-details/product-details.component.html">
|
|
||||||
</code-example>
|
|
||||||
|
|
||||||
<div class="alert is-helpful">
|
|
||||||
|
|
||||||
The line, `<h4>{{ product.price | currency }}</h4>` uses the `currency` pipe to transform `product.price` from a number to a currency string. A pipe is a way you can transform data in your HTML template. For more information about Angular pipes, see [Pipes](guide/pipes "Pipes").
|
|
||||||
|
|
||||||
</div>
|
|
||||||
|
|
||||||
1. To see the new "Buy" button, refresh the application and click on a product's name to display its details.
|
|
||||||
|
|
||||||
<div class="lightbox">
|
|
||||||
<img src='generated/images/guide/start/product-details-buy.png' alt="Display details for selected product with a Buy button">
|
|
||||||
</div>
|
|
||||||
|
|
||||||
1. Click the "Buy" button to add the product to the stored list of items in the cart and display a confirmation message.
|
|
||||||
|
|
||||||
<div class="lightbox">
|
|
||||||
<img src='generated/images/guide/start/buy-alert.png' alt="Display details for selected product with a Buy button">
|
|
||||||
</div>
|
|
||||||
|
|
||||||
|
|
||||||
## Create the cart view
|
|
||||||
|
|
||||||
At this point, users can put items in the cart by clicking "Buy", but they can't yet see their cart.
|
|
||||||
|
|
||||||
Create the cart view in two steps:
|
|
||||||
|
|
||||||
1. Create a cart component and configure routing to the new component. At this point, the cart view has only default text.
|
|
||||||
1. Display the cart items.
|
|
||||||
|
|
||||||
### Set up the component
|
|
||||||
|
|
||||||
To create the cart view, begin by following the same steps you did to create the product details component and configure routing for the new component.
|
|
||||||
|
|
||||||
1. Generate a cart component, named `cart`.
|
|
||||||
|
|
||||||
Reminder: In the file list, right-click the `app` folder, choose `Angular Generator` and `Component`.
|
|
||||||
|
|
||||||
<code-example header="src/app/cart/cart.component.ts" path="getting-started/src/app/cart/cart.component.1.ts"></code-example>
|
|
||||||
|
|
||||||
1. Add routing (a URL pattern) for the cart component.
|
|
||||||
|
|
||||||
Open `app.module.ts` and add a route for the component `CartComponent`, with a `path` of `cart`:
|
|
||||||
|
|
||||||
<code-example header="src/app/app.module.ts" path="getting-started/src/app/app.module.ts" region="cart-route">
|
|
||||||
</code-example>
|
|
||||||
|
|
||||||
1. Update the "Checkout" button so that it routes to the `/cart` url.
|
|
||||||
|
|
||||||
Open `top-bar.component.html` and add a `routerLink` directive pointing to `/cart`.
|
|
||||||
|
|
||||||
<code-example
|
|
||||||
header="src/app/top-bar/top-bar.component.html"
|
|
||||||
path="getting-started/src/app/top-bar/top-bar.component.html"
|
|
||||||
region="cart-route">
|
|
||||||
</code-example>
|
|
||||||
|
|
||||||
1. To see the new cart component, click the "Checkout" button. You can see the "cart works!" default text, and the URL has the pattern `https://getting-started.stackblitz.io/cart`, where `getting-started.stackblitz.io` may be different for your StackBlitz project.
|
|
||||||
|
|
||||||
<div class="lightbox">
|
|
||||||
<img src='generated/images/guide/start/cart-works.png' alt="Display cart view before customizing">
|
|
||||||
</div>
|
|
||||||
|
|
||||||
### Display the cart items
|
|
||||||
|
|
||||||
You can use services to share data across components:
|
|
||||||
|
|
||||||
* The product details component already uses the cart service to add products to the cart.
|
|
||||||
* This section shows you how to use the cart service to display the products in the cart.
|
|
||||||
|
|
||||||
|
|
||||||
1. Open `cart.component.ts`.
|
|
||||||
|
|
||||||
1. Configure the component to use the cart service.
|
|
||||||
|
|
||||||
1. Import the `CartService` from the `cart.service.ts` file.
|
|
||||||
|
|
||||||
<code-example header="src/app/cart/cart.component.ts" path="getting-started/src/app/cart/cart.component.2.ts" region="imports">
|
|
||||||
</code-example>
|
|
||||||
|
|
||||||
1. Inject the `CartService` so that the cart component can use it.
|
|
||||||
|
|
||||||
<code-example path="getting-started/src/app/cart/cart.component.2.ts" header="src/app/cart/cart.component.ts" region="inject-cart">
|
|
||||||
</code-example>
|
|
||||||
|
|
||||||
1. Define the `items` property to store the products in the cart.
|
|
||||||
|
|
||||||
<code-example path="getting-started/src/app/cart/cart.component.2.ts" header="src/app/cart/cart.component.ts" region="items">
|
|
||||||
</code-example>
|
|
||||||
|
|
||||||
1. Set the items using the cart service's `getItems()` method. Recall that you defined this method [when you generated `cart.service.ts`](#generate-cart-service).
|
|
||||||
|
|
||||||
The resulting `CartComponent` class is as follows:
|
|
||||||
|
|
||||||
<code-example path="getting-started/src/app/cart/cart.component.3.ts" header="src/app/cart/cart.component.ts" region="props-services">
|
|
||||||
</code-example>
|
|
||||||
|
|
||||||
1. Update the template with a header, and use a `<div>` with an `*ngFor` to display each of the cart items with its name and price.
|
|
||||||
|
|
||||||
The resulting `CartComponent` template is as follows:
|
|
||||||
|
|
||||||
<code-example header="src/app/cart/cart.component.html" path="getting-started/src/app/cart/cart.component.2.html" region="prices">
|
|
||||||
</code-example>
|
|
||||||
|
|
||||||
1. Test your cart component.
|
|
||||||
|
|
||||||
1. Click on "My Store" to go to the product list view.
|
|
||||||
1. Click on a product name to display its details.
|
|
||||||
1. Click "Buy" to add the product to the cart.
|
|
||||||
1. Click "Checkout" to see the cart.
|
|
||||||
1. To add another product, click "My Store" to return to the product list.
|
|
||||||
|
|
||||||
Repeat to add more items to the cart.
|
|
||||||
|
|
||||||
<div class="lightbox">
|
|
||||||
<img src='generated/images/guide/start/cart-page-full.png' alt="Cart view with products added">
|
|
||||||
</div>
|
|
||||||
|
|
||||||
|
|
||||||
<div class="alert is-helpful">
|
|
||||||
|
|
||||||
StackBlitz tip: Any time the preview refreshes, the cart is cleared. If you make changes to the app, the page refreshes, so you'll need to buy products again to populate the cart.
|
|
||||||
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="alert is-helpful">
|
|
||||||
|
|
||||||
For more information about services, see [Introduction to Services and Dependency Injection](guide/architecture-services "Concepts > Intro to Services and DI").
|
|
||||||
|
|
||||||
</div>
|
|
||||||
|
|
||||||
|
|
||||||
## Retrieve shipping prices
|
|
||||||
<!-- Accessing data with the HTTP client -->
|
|
||||||
|
|
||||||
Servers often return data in the form of a stream.
|
|
||||||
Streams are useful because they make it easy to transform the returned data and make modifications to the way you request that data.
|
|
||||||
The Angular HTTP client, `HttpClient`, is a built-in way to fetch data from external APIs and provide them to your app as a stream.
|
|
||||||
|
|
||||||
This section shows you how to use the HTTP client to retrieve shipping prices from an external file.
|
|
||||||
|
|
||||||
### Predefined shipping data
|
|
||||||
|
|
||||||
The application that StackBlitz generates for this guide comes with predefined shipping data in `assets/shipping.json`.
|
|
||||||
Use this data to add shipping prices for items in the cart.
|
|
||||||
|
|
||||||
<code-example header="src/assets/shipping.json" path="getting-started/src/assets/shipping.json">
|
|
||||||
</code-example>
|
|
||||||
|
|
||||||
|
|
||||||
### Use `HttpClient` in the `AppModule`
|
|
||||||
|
|
||||||
Before you can use Angular's HTTP client, you must configure your app to use `HttpClientModule`.
|
|
||||||
|
|
||||||
Angular's `HttpClientModule` registers the providers your app needs to use a single instance of the `HttpClient` service throughout your app.
|
|
||||||
|
|
||||||
1. Open `app.module.ts`.
|
|
||||||
|
|
||||||
This file contains imports and functionality that is available to the entire app.
|
|
||||||
|
|
||||||
1. Import `HttpClientModule` from the `@angular/common/http` package at the top of the file with the other imports. As there are a number of other imports, this code snippet omits them for brevity. Be sure to leave the existing imports in place.
|
|
||||||
|
|
||||||
<code-example header="src/app/app.module.ts" path="getting-started/src/app/app.module.ts" region="http-client-module-import">
|
|
||||||
</code-example>
|
|
||||||
|
|
||||||
1. Add `HttpClientModule` to the `AppModule` `@NgModule()` `imports` array to register Angular's `HttpClient` providers globally.
|
|
||||||
|
|
||||||
<code-example path="getting-started/src/app/app.module.ts" header="src/app/app.module.ts" region="http-client-module">
|
|
||||||
</code-example>
|
|
||||||
|
|
||||||
### Use `HttpClient` in the cart service
|
|
||||||
|
|
||||||
Now that the `AppModule` imports the `HttpClientModule`, the next step is to inject the `HttpClient` service into your service so your app can fetch data and interact with external APIs and resources.
|
|
||||||
|
|
||||||
|
|
||||||
1. Open `cart.service.ts`.
|
|
||||||
|
|
||||||
1. Import `HttpClient` from the `@angular/common/http` package.
|
|
||||||
|
|
||||||
<code-example header="src/app/cart.service.ts" path="getting-started/src/app/cart.service.ts" region="import-http">
|
|
||||||
</code-example>
|
|
||||||
|
|
||||||
1. Inject `HttpClient` into the `CartService` constructor:
|
|
||||||
|
|
||||||
<code-example path="getting-started/src/app/cart.service.ts" header="src/app/cart.service.ts" region="inject-http">
|
|
||||||
</code-example>
|
|
||||||
|
|
||||||
|
|
||||||
### Define the `get()` method
|
|
||||||
|
|
||||||
Multiple components can leverage the same service.
|
|
||||||
Later in this tutorial, the shipping component uses the cart service to retrieve shipping data via HTTP from the `shipping.json` file.
|
|
||||||
First, define a `get()` method.
|
|
||||||
|
|
||||||
1. Continue working in `cart.service.ts`.
|
|
||||||
|
|
||||||
1. Below the `clearCart()` method, define a new `getShippingPrices()` method that uses the `HttpClient` `get()` method to retrieve the shipping data.
|
|
||||||
|
|
||||||
<code-example header="src/app/cart.service.ts" path="getting-started/src/app/cart.service.ts" region="get-shipping"></code-example>
|
|
||||||
|
|
||||||
|
|
||||||
<div class="alert is-helpful">
|
|
||||||
|
|
||||||
For more information about Angular's `HttpClient`, see the [Client-Server Interaction](guide/http "Server interaction through HTTP") guide.
|
|
||||||
|
|
||||||
</div>
|
|
||||||
|
|
||||||
## Define the shipping view
|
|
||||||
|
|
||||||
Now that your app can retrieve shipping data, create a shipping component and template.
|
|
||||||
|
|
||||||
1. Generate a new component named `shipping`.
|
|
||||||
|
|
||||||
Reminder: In the file list, right-click the `app` folder, choose `Angular Generator` and `Component`.
|
|
||||||
|
|
||||||
<code-example header="src/app/shipping/shipping.component.ts" path="getting-started/src/app/shipping/shipping.component.1.ts"></code-example>
|
|
||||||
|
|
||||||
1. In `app.module.ts`, add a route for shipping. Specify a `path` of `shipping` and a component of `ShippingComponent`.
|
|
||||||
|
|
||||||
<code-example header="src/app/app.module.ts" path="getting-started/src/app/app.module.ts" region="shipping-route"></code-example>
|
|
||||||
|
|
||||||
There's no link to the new shipping component yet, but you can see its template in the preview pane by entering the URL its route specifies. The URL has the pattern: `https://getting-started.stackblitz.io/shipping` where the `getting-started.stackblitz.io` part may be different for your StackBlitz project.
|
|
||||||
|
|
||||||
1. Modify the shipping component so that it uses the cart service to retrieve shipping data via HTTP from the `shipping.json` file.
|
|
||||||
|
|
||||||
1. Import the cart service.
|
|
||||||
|
|
||||||
<code-example header="src/app/shipping/shipping.component.ts" path="getting-started/src/app/shipping/shipping.component.ts" region="imports"></code-example>
|
|
||||||
|
|
||||||
1. Define a `shippingCosts` property.
|
|
||||||
|
|
||||||
<code-example path="getting-started/src/app/shipping/shipping.component.ts" header="src/app/shipping/shipping.component.ts" region="props"></code-example>
|
|
||||||
|
|
||||||
1. Inject the cart service in the `ShippingComponent` constructor:
|
|
||||||
|
|
||||||
<code-example path="getting-started/src/app/shipping/shipping.component.ts" header="src/app/shipping/shipping.component.ts" region="inject-cart-service"></code-example>
|
|
||||||
|
|
||||||
1. Set the `shippingCosts` property using the `getShippingPrices()` method from the cart service.
|
|
||||||
|
|
||||||
<code-example path="getting-started/src/app/shipping/shipping.component.ts" header="src/app/shipping/shipping.component.ts" region="ctor"></code-example>
|
|
||||||
|
|
||||||
1. Update the shipping component's template to display the shipping types and prices using the `async` pipe:
|
|
||||||
|
|
||||||
<code-example header="src/app/shipping/shipping.component.html" path="getting-started/src/app/shipping/shipping.component.html"></code-example>
|
|
||||||
|
|
||||||
The `async` pipe returns the latest value from a stream of data and continues to do so for the life of a given component. When Angular destroys that component, the `async` pipe automatically stops. For detailed information about the `async` pipe, see the [AsyncPipe API documentation](/api/common/AsyncPipe).
|
|
||||||
|
|
||||||
1. Add a link from the cart view to the shipping view:
|
|
||||||
|
|
||||||
<code-example header="src/app/cart/cart.component.html" path="getting-started/src/app/cart/cart.component.2.html"></code-example>
|
|
||||||
|
|
||||||
1. Test your shipping prices feature:
|
|
||||||
|
|
||||||
Click the "Checkout" button to see the updated cart. Remember that changing the app causes the preview to refresh, which empties the cart.
|
|
||||||
|
|
||||||
<div class="lightbox">
|
|
||||||
<img src='generated/images/guide/start/cart-empty-with-shipping-prices.png' alt="Cart with link to shipping prices">
|
|
||||||
</div>
|
|
||||||
|
|
||||||
Click on the link to navigate to the shipping prices.
|
|
||||||
|
|
||||||
<div class="lightbox">
|
|
||||||
<img src='generated/images/guide/start/shipping-prices.png' alt="Display shipping prices">
|
|
||||||
</div>
|
|
||||||
|
|
||||||
|
|
||||||
## Next steps
|
|
||||||
|
|
||||||
Congratulations! You have an online store application with a product catalog and shopping cart. You can also look up and display shipping prices.
|
|
||||||
|
|
||||||
To continue exploring Angular, choose either of the following options:
|
|
||||||
* [Continue to the "Forms" section](start/start-forms "Try it: Forms for User Input") to finish the app by adding the shopping cart view and a checkout form.
|
|
||||||
* [Skip ahead to the "Deployment" section](start/start-deployment "Try it: Deployment") to move to local development, or deploy your app to Firebase or your own server.
|
|
@ -1,106 +1,113 @@
|
|||||||
# Navegación en la aplicación
|
# In-app navigation
|
||||||
|
|
||||||
Al final de la [parte 1] (start "Empieza con una aplicación Angular básica"), la aplicación de la tienda en línea tiene un catálogo básico de productos. La aplicación no tiene ningun estado de variable o navegación. Hay una URL, y esa URL siempre muestra la pagina "Mi Tienda" con una lista de productos y sus descripciones.
|
At the end of [part 1](start "Get started with a basic Angular app"), the online store application has a basic product catalog.
|
||||||
|
The app doesn't have any variable states or navigation.
|
||||||
|
There is one URL, and that URL always displays the "My Store" page with a list of products and their descriptions.
|
||||||
|
|
||||||
Esta guía te muestra cómo usar Angular [Routing](guide/glossary#router "Definición de Router") para brindarle al usuario navegación dentro de la aplicación. En una aplicación de una sola página, en lugar de cargar nuevas páginas, muestras diferentes componentes y datos al usuario en función de dónde se encuentra el usuario en la aplicación.
|
This guide shows you how to use Angular [routing](guide/glossary#router "Router definition") to give the user in-app navigation. In a single-page app, instead of loading new pages, you show different components and data to the user based on where the user is in the application.
|
||||||
|
|
||||||
El router te permite mostrar los detalles completos del producto en [vistas](guide/glossary#view "Definición de vista") separadas, cada una con su propia URL. El router habilita la navegación de una vista a la siguiente (dentro de la misma página) cuando los usuarios realizan tareas como las siguientes:
|
The router lets you display full product details in separate [views](guide/glossary#view "View definition"), each with its own URL. Routing enables navigation from one view to the next (within the same page) as users perform tasks such as the following:
|
||||||
|
|
||||||
* Ingresando una URL en la barra de direcciones para navegar a la vista correspondiente.
|
* Entering a URL in the address bar to navigate to a corresponding view.
|
||||||
* Haciendo clic en los enlaces de la página para navegar a una nueva vista.
|
* Clicking links on the page to navigate to a new view.
|
||||||
* Haciendo clic en los botones de adelante y atrás del navegador para navegar hacia atrás y hacia adelante a través del historial del navegador.
|
* Clicking the browser's back and forward buttons to navigate backward and forward through the browser history.
|
||||||
|
|
||||||
## Registro de una ruta
|
## Registering a route
|
||||||
|
|
||||||
La aplicación ya esta configurada para usar el Angular `Router` y usar el Routing para navegar al componente de la lista de productos que modificaste anteriormente. Esta sección te muestra cómo definir una ruta para mostrar los detalles de productos individualmente.
|
The app is already set up to use the Angular `Router` and to use routing to navigate to the product list component you modified earlier. This section shows you how to define a route to show individual product details.
|
||||||
|
|
||||||
1. Genera un nuevo componente para los detalles del producto. Asigna al componente el nombre `product-details`.
|
1. Generate a new component for product details. Give the component the name `product-details`.
|
||||||
|
|
||||||
Recuerda: En la lista de archivos, haz clic con el botón derecho en la carpeta `app`, selecciona `Angular Generator` y `Component`.
|
Reminder: In the file list, right-click the `app` folder, choose `Angular Generator` and `Component`.
|
||||||
|
|
||||||
2. En `app.module.ts`, agrega una ruta para los detalles del producto, con un `path` de `products/:productId` y `ProductDetailsComponent` para el `component`.
|
1. In `app.module.ts`, add a route for product details, with a `path` of `products/:productId` and `ProductDetailsComponent` for the `component`.
|
||||||
|
|
||||||
<code-example header="src/app/app.module.ts" path="getting-started/src/app/app.module.ts" region="product-details-route">
|
<code-example header="src/app/app.module.ts" path="getting-started/src/app/app.module.ts" region="product-details-route">
|
||||||
</code-example>
|
</code-example>
|
||||||
|
|
||||||
Una ruta asocia una o más URL con un componente.
|
A route associates one or more URL paths with a component.
|
||||||
|
|
||||||
3. La directiva configura la plantilla del componente para definir cómo el usuario navega a la ruta o URL. Cuando el usuario hace clic en el nombre de un producto, la aplicación muestra los detalles de ese producto.
|
1. The directive configures the component template to define how the user navigates to the route or URL. When the user clicks a product name, the app displays the details for that product.
|
||||||
|
|
||||||
1. Abre `product-list.component.html`.
|
1. Open `product-list.component.html`.
|
||||||
|
|
||||||
1. Actualiza la directiva `*ngFor` para asignar cada índice en la matriz `products` a la variable `productId` cuando se itera sobre la lista.
|
1. Update the `*ngFor` directive to assign each index in the `products` array to the `productId` variable when iterating over the list.
|
||||||
|
|
||||||
1. Modifica el ancla del nombre del producto para incluir un `routerLink`.
|
1. Modify the product name anchor to include a `routerLink`.
|
||||||
|
|
||||||
<code-example header="src/app/product-list/product-list.component.html" path="getting-started/src/app/product-list/product-list.component.html" region="router-link">
|
<code-example header="src/app/product-list/product-list.component.html" path="getting-started/src/app/product-list/product-list.component.html" region="router-link">
|
||||||
</code-example>
|
</code-example>
|
||||||
|
|
||||||
La directiva RouterLink le da al Router el control sobre el elemento de anclaje. En este caso, la ruta, o URL, contiene un segmento fijo, `/products`, mientras que el segmento final es variable, insertando la propiedad id del producto actual. Por ejemplo, la URL de un producto con un `id` de 1 será similar a `https://getting-started-myfork.stackblitz.io/products/1`.
|
The RouterLink directive gives the router control over the anchor element. In this case, the route, or URL, contains one fixed segment, `/products`, while the final segment is variable, inserting the id property of the current product. For example, the URL for a product with an `id` of 1 will be similar to `https://getting-started-myfork.stackblitz.io/products/1`.
|
||||||
|
|
||||||
4. Prueba el Router haciendo clic en el nombre de un producto. La aplicación muestra el componente de detalles del producto, que actualmente siempre dice "product-details works!"
|
1. Test the router by clicking a product name. The app displays the product details component, which currently always says "product-details works!"
|
||||||
|
|
||||||
Observa que cambia la URL en la ventana de vista previa. El segmento final es "products/#" donde "#" es el número de la ruta en la que hizo clic.
|
Notice that the URL in the preview window changes. The final segment is `products/#` where `#` is the number of the route you clicked.
|
||||||
|
|
||||||
<div class="lightbox">
|
<div class="lightbox">
|
||||||
<img src="generated/images/guide/start/product-details-works.png" alt="Vista de detalles del producto con URL actualizada">
|
<img src="generated/images/guide/start/product-details-works.png" alt="Product details view with updated URL">
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
## Utilizar información de la ruta
|
|
||||||
|
|
||||||
El componente de detalles del producto maneja la visualización de cada producto. El Angular Router muestra los componentes basados en la URL del navegador y sus rutas definidas. Esta sección te muestra cómo usar el Angular Router para combinar los datos de los `productos` y la información de la ruta para mostrar los detalles específicos de cada producto.
|
|
||||||
|
|
||||||
1. Abre `product-details.component.ts`
|
## Using route information
|
||||||
|
|
||||||
2. Organiza el uso de datos de productos desde un archivo externo.
|
The product details component handles the display of each product. The Angular Router displays components based on the browser's URL and your defined routes. This section shows you how to use the Angular Router to combine the `products` data and route information to display the specific details for each product.
|
||||||
|
|
||||||
1. Importa `ActivatedRoute` del paquete `@angular/router` y la matriz `products` de `../products`.
|
1. Open `product-details.component.ts`
|
||||||
|
|
||||||
|
1. Arrange to use product data from an external file.
|
||||||
|
|
||||||
|
1. Import `ActivatedRoute` from the `@angular/router` package, and the `products` array from `../products`.
|
||||||
|
|
||||||
<code-example header="src/app/product-details/product-details.component.ts" path="getting-started/src/app/product-details/product-details.component.1.ts" region="imports">
|
<code-example header="src/app/product-details/product-details.component.ts" path="getting-started/src/app/product-details/product-details.component.1.ts" region="imports">
|
||||||
</code-example>
|
</code-example>
|
||||||
|
|
||||||
1. Define la propiedad `product` e inyecta el `ActivatedRoute` en el constructor agregándolo como un argumento dentro de los paréntesis del constructor.
|
1. Define the `product` property and inject the `ActivatedRoute` into the constructor by adding it as an argument within the constructor's parentheses.
|
||||||
|
|
||||||
<code-example header="src/app/product-details/product-details.component.ts" path="getting-started/src/app/product-details/product-details.component.1.ts" region="props-methods">
|
<code-example header="src/app/product-details/product-details.component.ts" path="getting-started/src/app/product-details/product-details.component.1.ts" region="props-methods">
|
||||||
</code-example>
|
</code-example>
|
||||||
|
|
||||||
El `ActivatedRoute` es específico para cada componente enrutado que carga el Angular Router. Contiene información sobre la
|
The `ActivatedRoute` is specific to each routed component that the Angular Router loads. It contains information about the
|
||||||
ruta, sus parámetros y datos adicionales asociados con la ruta.
|
route, its parameters, and additional data associated with the route.
|
||||||
|
|
||||||
Inyectando el `ActivatedRoute`, estás configurando el componente para usar un *servicio*. La página [Manejo de Datos] (start/start-data "Pruébalo: Manejo de Datos") cubre los servicios con más detalle.
|
By injecting the `ActivatedRoute`, you are configuring the component to use a *service*. The [Managing Data](start/start-data "Try it: Managing Data") page covers services in more detail.
|
||||||
|
|
||||||
|
|
||||||
3. En el método `ngOnInit()`, suscríbete a los parámetros de ruta y obtén el producto basándote en el `productId`.
|
1. In the `ngOnInit()` method, subscribe to route parameters and fetch the product based on the `productId`.
|
||||||
|
|
||||||
<code-example path="getting-started/src/app/product-details/product-details.component.1.ts" header="src/app/product-details/product-details.component.ts" region="get-product">
|
<code-example path="getting-started/src/app/product-details/product-details.component.1.ts" header="src/app/product-details/product-details.component.ts" region="get-product">
|
||||||
</code-example>
|
</code-example>
|
||||||
|
|
||||||
Los parámetros de la ruta corresponden a las variables de ruta (path) que se define en la ruta. La URL que coincide con la ruta proporciona el `productId`. Angular usa el `productId` para mostrar los detalles de cada producto único.
|
The route parameters correspond to the path variables you define in the route. The URL that matches the route provides the `productId`. Angular uses the `productId` to display the details for each unique product.
|
||||||
|
|
||||||
4. Actualiza la plantilla para mostrar la información de detalle del producto dentro de un `*ngIf`.
|
1. Update the template to display product details information inside an `*ngIf`.
|
||||||
|
|
||||||
<code-example header="src/app/product-details/product-details.component.html" path="getting-started/src/app/product-details/product-details.component.html" region="details">
|
<code-example header="src/app/product-details/product-details.component.html" path="getting-started/src/app/product-details/product-details.component.html" region="details">
|
||||||
</code-example>
|
</code-example>
|
||||||
|
|
||||||
Ahora, cuando los usuarios hacen clic en un nombre en la lista de productos, el router los dirige a la URL distinta del producto, cambia el componente de la lista de productos por el componente de detalles del producto y muestra los detalles del producto.
|
Now, when users click on a name in the product list, the router navigates them to the distinct URL for the product, swaps out the product list component for the product details component, and displays the product details.
|
||||||
|
|
||||||
<div class="lightbox">
|
<div class="lightbox">
|
||||||
<img src="generated/images/guide/start/product-details-routed.png" alt="Página de detalles del producto con URL actualizada y detalles completos mostrados">
|
<img src="generated/images/guide/start/product-details-routed.png" alt="Product details page with updated URL and full details displayed">
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<div class="alert is-helpful">
|
<div class="alert is-helpful">
|
||||||
|
|
||||||
Para obtener más información sobre el Angular Router, consulta [Enrutamiento y Navegación] (guide/router "Guía de Enrutamiento y Navegación").
|
For more information about the Angular Router, see [Routing & Navigation](guide/router "Routing & Navigation guide").
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
## Próximos pasos
|
|
||||||
|
|
||||||
¡Felicidades! Has integrado el enrutamiento en tu tienda en linea.
|
## Next steps
|
||||||
|
|
||||||
* Los productos están vinculados desde la vista de lista de productos a productos individuales.
|
Congratulations! You have integrated routing into your online store.
|
||||||
* Los usuarios pueden hacer clic en el nombre de un producto de la lista para ver los detalles en una nueva vista, con una URL / ruta distinta.
|
|
||||||
|
|
||||||
Para continuar explorando Angular, elige cualquiera de las siguientes opciones:
|
* Products are linked from the product list view to individual products.
|
||||||
* [Continuar con la sección "Manejo de Datos"] (start/start-data "Pruébalo: Manejo de datos") para agregar una función de carrito de compras, usa un servicio para administrar los datos del carrito y usa HTTP para recuperar datos externos para los precios del envío.
|
* Users can click on a product name from the list to see details in a new view, with a distinct URL/route.
|
||||||
* [Ir a la sección Despliegue] (start/start-deployment "Pruébalo: Despliegue") para implementar su aplicación en Firebase o pasar al desarrollo local.
|
|
||||||
|
To continue exploring Angular, choose either of the following options:
|
||||||
|
* [Continue to the "Managing Data" section](start/start-data "Try it: Managing Data") to add a shopping cart feature, use a service to manage the cart data and use HTTP to retrieve external data for shipping prices.
|
||||||
|
* [Skip ahead to the Deployment section](start/start-deployment "Try it: Deployment") to deploy your app to Firebase or move to local development.
|
||||||
|
@ -5,7 +5,7 @@
|
|||||||
|
|
||||||
En este tutorial, crearás tu propia aplicación desde cero, proporcionando experiencia con el proceso de desarrollo típico, así como una introducción a los conceptos básicos de diseño de aplicaciones, herramientas y terminología.
|
En este tutorial, crearás tu propia aplicación desde cero, proporcionando experiencia con el proceso de desarrollo típico, así como una introducción a los conceptos básicos de diseño de aplicaciones, herramientas y terminología.
|
||||||
|
|
||||||
Si eres completamente nuevo en Angular, es posible que desees probar la aplicación de inicio rápido [**Pruébalo ahora**](start) primero.
|
Si eres completamente nuevo en Angular, es posible que desees probar la aplicación de inicio rápido [**Pruébelo ahora **](start) primero.
|
||||||
Se basa en un proyecto listo y parcialmente completado, que puedes examinar y modificar en el entorno de desarrollo interactivo de StackBlitz, donde puedes ver los resultados en tiempo real.
|
Se basa en un proyecto listo y parcialmente completado, que puedes examinar y modificar en el entorno de desarrollo interactivo de StackBlitz, donde puedes ver los resultados en tiempo real.
|
||||||
|
|
||||||
El tutorial "Pruébalo" cubre los mismos temas principales—componentes, sintaxis de plantilla, enrutamiento, servicios y acceso a datos a través de HTTP— en un formato condensado, siguiendo las mejores prácticas más actuales.
|
El tutorial "Pruébalo" cubre los mismos temas principales—componentes, sintaxis de plantilla, enrutamiento, servicios y acceso a datos a través de HTTP— en un formato condensado, siguiendo las mejores prácticas más actuales.
|
||||||
@ -29,9 +29,9 @@ Al final de este tutorial, podrás hacer lo siguiente:
|
|||||||
* Agregar campos editables para actualizar un modelo con enlace de datos bidireccional.
|
* Agregar campos editables para actualizar un modelo con enlace de datos bidireccional.
|
||||||
* Enlazar métodos de componentes a eventos de usuario, como pulsaciones de teclas y clics.
|
* Enlazar métodos de componentes a eventos de usuario, como pulsaciones de teclas y clics.
|
||||||
* Permitir a los usuarios seleccionar un héroe de una lista maestra y editar ese héroe en la vista de detalles.
|
* Permitir a los usuarios seleccionar un héroe de una lista maestra y editar ese héroe en la vista de detalles.
|
||||||
* Dar formato a datos con [pipes](guide/glossary#pipe "Definición de Pipe").
|
* Dar formato a datos con [pipes](guide/glossary#pipe "Definición de Pipe ")
|
||||||
* Crear un [servicio](guide/glossary#service "Definición de Servicio") compartido para reunir a los héroes.
|
* Crear un [servicio](guide/glossary#service "Definición de Servicio") compartido para reunir a los héroes.
|
||||||
* Utilizar [enrutamiento](guide/glossary#router "Definición de Enrutamiento") para navegar entre diferentes vistas y sus componentes.
|
* Utilizar [enrutamiento](guide/glossary#router "Definición de Enrutamiento ")(routing) para navegar entre diferentes vistas y sus componentes.
|
||||||
|
|
||||||
Aprenderás suficiente Angular para comenzar y ganarás la confianza de que
|
Aprenderás suficiente Angular para comenzar y ganarás la confianza de que
|
||||||
Angular puede hacer lo que tú necesites que haga.
|
Angular puede hacer lo que tú necesites que haga.
|
||||||
|
@ -1,253 +0,0 @@
|
|||||||
# Display a selection list
|
|
||||||
|
|
||||||
In this page, you'll expand the Tour of Heroes app to display a list of heroes, and
|
|
||||||
allow users to select a hero and display the hero's details.
|
|
||||||
|
|
||||||
<div class="alert is-helpful">
|
|
||||||
|
|
||||||
For the sample app that this page describes, see the <live-example></live-example>.
|
|
||||||
|
|
||||||
</div>
|
|
||||||
|
|
||||||
|
|
||||||
## Create mock heroes
|
|
||||||
|
|
||||||
You'll need some heroes to display.
|
|
||||||
|
|
||||||
Eventually you'll get them from a remote data server.
|
|
||||||
For now, you'll create some _mock heroes_ and pretend they came from the server.
|
|
||||||
|
|
||||||
Create a file called `mock-heroes.ts` in the `src/app/` folder.
|
|
||||||
Define a `HEROES` constant as an array of ten heroes and export it.
|
|
||||||
The file should look like this.
|
|
||||||
|
|
||||||
<code-example path="toh-pt2/src/app/mock-heroes.ts" header="src/app/mock-heroes.ts"></code-example>
|
|
||||||
|
|
||||||
## Displaying heroes
|
|
||||||
|
|
||||||
Open the `HeroesComponent` class file and import the mock `HEROES`.
|
|
||||||
|
|
||||||
<code-example path="toh-pt2/src/app/heroes/heroes.component.ts" region="import-heroes" header="src/app/heroes/heroes.component.ts (import HEROES)">
|
|
||||||
</code-example>
|
|
||||||
|
|
||||||
In the same file (`HeroesComponent` class), define a component property called `heroes` to expose the `HEROES` array for binding.
|
|
||||||
|
|
||||||
<code-example path="toh-pt2/src/app/heroes/heroes.component.ts" header="src/app/heroes/heroes.component.ts" region="component">
|
|
||||||
</code-example>
|
|
||||||
|
|
||||||
### List heroes with `*ngFor`
|
|
||||||
|
|
||||||
Open the `HeroesComponent` template file and make the following changes:
|
|
||||||
|
|
||||||
* Add an `<h2>` at the top,
|
|
||||||
* Below it add an HTML unordered list (`<ul>`)
|
|
||||||
* Insert an `<li>` within the `<ul>` that displays properties of a `hero`.
|
|
||||||
* Sprinkle some CSS classes for styling (you'll add the CSS styles shortly).
|
|
||||||
|
|
||||||
Make it look like this:
|
|
||||||
|
|
||||||
<code-example path="toh-pt2/src/app/heroes/heroes.component.1.html" region="list" header="heroes.component.html (heroes template)"></code-example>
|
|
||||||
|
|
||||||
That shows one hero. To list them all, add an `*ngFor` to the `<li>` to iterate through the list of heroes:
|
|
||||||
|
|
||||||
<code-example path="toh-pt2/src/app/heroes/heroes.component.1.html" region="li">
|
|
||||||
</code-example>
|
|
||||||
|
|
||||||
The [`*ngFor`](guide/built-in-directives#ngFor) is Angular's _repeater_ directive.
|
|
||||||
It repeats the host element for each element in a list.
|
|
||||||
|
|
||||||
The syntax in this example is as follows:
|
|
||||||
|
|
||||||
* `<li>` is the host element.
|
|
||||||
* `heroes` holds the mock heroes list from the `HeroesComponent` class, the mock heroes list.
|
|
||||||
* `hero` holds the current hero object for each iteration through the list.
|
|
||||||
|
|
||||||
<div class="alert is-important">
|
|
||||||
|
|
||||||
Don't forget the asterisk (*) in front of `ngFor`. It's a critical part of the syntax.
|
|
||||||
|
|
||||||
</div>
|
|
||||||
|
|
||||||
After the browser refreshes, the list of heroes appears.
|
|
||||||
|
|
||||||
{@a styles}
|
|
||||||
|
|
||||||
### Style the heroes
|
|
||||||
|
|
||||||
The heroes list should be attractive and should respond visually when users
|
|
||||||
hover over and select a hero from the list.
|
|
||||||
|
|
||||||
In the [first tutorial](tutorial/toh-pt0#app-wide-styles), you set the basic styles for the entire application in `styles.css`.
|
|
||||||
That stylesheet didn't include styles for this list of heroes.
|
|
||||||
|
|
||||||
You could add more styles to `styles.css` and keep growing that stylesheet as you add components.
|
|
||||||
|
|
||||||
You may prefer instead to define private styles for a specific component and keep everything a component needs— the code, the HTML,
|
|
||||||
and the CSS —together in one place.
|
|
||||||
|
|
||||||
This approach makes it easier to re-use the component somewhere else
|
|
||||||
and deliver the component's intended appearance even if the global styles are different.
|
|
||||||
|
|
||||||
You define private styles either inline in the `@Component.styles` array or
|
|
||||||
as stylesheet file(s) identified in the `@Component.styleUrls` array.
|
|
||||||
|
|
||||||
When the CLI generated the `HeroesComponent`, it created an empty `heroes.component.css` stylesheet for the `HeroesComponent`
|
|
||||||
and pointed to it in `@Component.styleUrls` like this.
|
|
||||||
|
|
||||||
<code-example path="toh-pt2/src/app/heroes/heroes.component.ts" region="metadata"
|
|
||||||
header="src/app/heroes/heroes.component.ts (@Component)">
|
|
||||||
</code-example>
|
|
||||||
|
|
||||||
Open the `heroes.component.css` file and paste in the private CSS styles for the `HeroesComponent`.
|
|
||||||
You'll find them in the [final code review](#final-code-review) at the bottom of this guide.
|
|
||||||
|
|
||||||
<div class="alert is-important">
|
|
||||||
|
|
||||||
Styles and stylesheets identified in `@Component` metadata are scoped to that specific component.
|
|
||||||
The `heroes.component.css` styles apply only to the `HeroesComponent` and don't affect the outer HTML or the HTML in any other component.
|
|
||||||
|
|
||||||
</div>
|
|
||||||
|
|
||||||
## Master/Detail
|
|
||||||
|
|
||||||
When the user clicks a hero in the **master** list,
|
|
||||||
the component should display the selected hero's **details** at the bottom of the page.
|
|
||||||
|
|
||||||
In this section, you'll listen for the hero item click event
|
|
||||||
and update the hero detail.
|
|
||||||
|
|
||||||
### Add a click event binding
|
|
||||||
|
|
||||||
Add a click event binding to the `<li>` like this:
|
|
||||||
|
|
||||||
<code-example path="toh-pt2/src/app/heroes/heroes.component.1.html" region="selectedHero-click" header="heroes.component.html (template excerpt)"></code-example>
|
|
||||||
|
|
||||||
This is an example of Angular's [event binding](guide/event-binding) syntax.
|
|
||||||
|
|
||||||
The parentheses around `click` tell Angular to listen for the `<li>` element's `click` event.
|
|
||||||
When the user clicks in the `<li>`, Angular executes the `onSelect(hero)` expression.
|
|
||||||
|
|
||||||
|
|
||||||
In the next section, define an `onSelect()` method in `HeroesComponent` to
|
|
||||||
display the hero that was defined in the `*ngFor` expression.
|
|
||||||
|
|
||||||
|
|
||||||
### Add the click event handler
|
|
||||||
|
|
||||||
Rename the component's `hero` property to `selectedHero` but don't assign it.
|
|
||||||
There is no _selected hero_ when the application starts.
|
|
||||||
|
|
||||||
Add the following `onSelect()` method, which assigns the clicked hero from the template
|
|
||||||
to the component's `selectedHero`.
|
|
||||||
|
|
||||||
<code-example path="toh-pt2/src/app/heroes/heroes.component.ts" region="on-select" header="src/app/heroes/heroes.component.ts (onSelect)"></code-example>
|
|
||||||
|
|
||||||
### Add a details section
|
|
||||||
|
|
||||||
Currently, you have a list in the component template. To click on a hero on the list
|
|
||||||
and reveal details about that hero, you need a section for the details to render in the
|
|
||||||
template. Add the following to `heroes.component.html` beneath the list section:
|
|
||||||
|
|
||||||
<code-example path="toh-pt2/src/app/heroes/heroes.component.html" region="selectedHero-details" header="heroes.component.html (selected hero details)"></code-example>
|
|
||||||
|
|
||||||
After the browser refreshes, the application is broken.
|
|
||||||
|
|
||||||
Open the browser developer tools and look in the console for an error message like this:
|
|
||||||
|
|
||||||
<code-example language="sh" class="code-shell">
|
|
||||||
HeroesComponent.html:3 ERROR TypeError: Cannot read property 'name' of undefined
|
|
||||||
</code-example>
|
|
||||||
|
|
||||||
#### What happened?
|
|
||||||
|
|
||||||
When the app starts, the `selectedHero` is `undefined` _by design_.
|
|
||||||
|
|
||||||
Binding expressions in the template that refer to properties of `selectedHero`—expressions like `{{selectedHero.name}}`—_must fail_ because there is no selected hero.
|
|
||||||
|
|
||||||
|
|
||||||
#### The fix - hide empty details with _*ngIf_
|
|
||||||
|
|
||||||
|
|
||||||
The component should only display the selected hero details if the `selectedHero` exists.
|
|
||||||
|
|
||||||
Wrap the hero detail HTML in a `<div>`.
|
|
||||||
Add Angular's `*ngIf` directive to the `<div>` and set it to `selectedHero`.
|
|
||||||
|
|
||||||
|
|
||||||
<div class="alert is-important">
|
|
||||||
|
|
||||||
Don't forget the asterisk (*) in front of `ngIf`. It's a critical part of the syntax.
|
|
||||||
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<code-example path="toh-pt2/src/app/heroes/heroes.component.html" region="ng-if" header="src/app/heroes/heroes.component.html (*ngIf)"></code-example>
|
|
||||||
|
|
||||||
After the browser refreshes, the list of names reappears.
|
|
||||||
The details area is blank.
|
|
||||||
Click a hero in the list of heroes and its details appear.
|
|
||||||
The app seems to be working again.
|
|
||||||
The heroes appear in a list and details about the clicked hero appear at the bottom of the page.
|
|
||||||
|
|
||||||
|
|
||||||
#### Why it works
|
|
||||||
|
|
||||||
When `selectedHero` is undefined, the `ngIf` removes the hero detail from the DOM. There are no `selectedHero` bindings to consider.
|
|
||||||
|
|
||||||
When the user picks a hero, `selectedHero` has a value and
|
|
||||||
`ngIf` puts the hero detail into the DOM.
|
|
||||||
|
|
||||||
### Style the selected hero
|
|
||||||
|
|
||||||
It's difficult to identify the _selected hero_ in the list when all `<li>` elements look alike.
|
|
||||||
|
|
||||||
If the user clicks "Magneta", that hero should render with a distinctive but subtle background color like this:
|
|
||||||
|
|
||||||
<div class="lightbox">
|
|
||||||
<img src='generated/images/guide/toh/heroes-list-selected.png' alt="Selected hero">
|
|
||||||
</div>
|
|
||||||
|
|
||||||
That _selected hero_ coloring is the work of the `.selected` CSS class in the [styles you added earlier](#styles).
|
|
||||||
You just have to apply the `.selected` class to the `<li>` when the user clicks it.
|
|
||||||
|
|
||||||
The Angular [class binding](guide/attribute-binding#class-binding) makes it easy to add and remove a CSS class conditionally.
|
|
||||||
Just add `[class.some-css-class]="some-condition"` to the element you want to style.
|
|
||||||
|
|
||||||
Add the following `[class.selected]` binding to the `<li>` in the `HeroesComponent` template:
|
|
||||||
|
|
||||||
<code-example path="toh-pt2/src/app/heroes/heroes.component.1.html" region="class-selected" header="heroes.component.html (toggle the 'selected' CSS class)"></code-example>
|
|
||||||
|
|
||||||
When the current row hero is the same as the `selectedHero`, Angular adds the `selected` CSS class. When the two heroes are different, Angular removes the class.
|
|
||||||
|
|
||||||
The finished `<li>` looks like this:
|
|
||||||
|
|
||||||
<code-example path="toh-pt2/src/app/heroes/heroes.component.html" region="li" header="heroes.component.html (list item hero)"></code-example>
|
|
||||||
|
|
||||||
{@a final-code-review}
|
|
||||||
|
|
||||||
## Final code review
|
|
||||||
|
|
||||||
Here are the code files discussed on this page, including the `HeroesComponent` styles.
|
|
||||||
|
|
||||||
<code-tabs>
|
|
||||||
|
|
||||||
<code-pane header="src/app/mock-heroes.ts" path="toh-pt2/src/app/mock-heroes.ts">
|
|
||||||
</code-pane>
|
|
||||||
|
|
||||||
<code-pane header="src/app/heroes/heroes.component.ts" path="toh-pt2/src/app/heroes/heroes.component.ts">
|
|
||||||
</code-pane>
|
|
||||||
|
|
||||||
<code-pane header="src/app/heroes/heroes.component.html" path="toh-pt2/src/app/heroes/heroes.component.html">
|
|
||||||
</code-pane>
|
|
||||||
|
|
||||||
<code-pane header="src/app/heroes/heroes.component.css" path="toh-pt2/src/app/heroes/heroes.component.css">
|
|
||||||
</code-pane>
|
|
||||||
|
|
||||||
</code-tabs>
|
|
||||||
|
|
||||||
## Summary
|
|
||||||
|
|
||||||
* The Tour of Heroes app displays a list of heroes in a Master/Detail view.
|
|
||||||
* The user can select a hero and see that hero's details.
|
|
||||||
* You used `*ngFor` to display a list.
|
|
||||||
* You used `*ngIf` to conditionally include or exclude a block of HTML.
|
|
||||||
* You can toggle a CSS style class with a `class` binding.
|
|
@ -1,217 +1,232 @@
|
|||||||
# Mostrar una lista de selección
|
# Display a selection list
|
||||||
|
|
||||||
En esta página, ampliaremos la aplicación Tour de Héroes para mostrar una lista de héroes,
|
In this page, you'll expand the Tour of Heroes app to display a list of heroes, and
|
||||||
Permite al usuario seleccionar un héroe y ver los detalles del héroe.
|
allow users to select a hero and display the hero's details.
|
||||||
|
|
||||||
<div class="alert is-helpful">
|
<div class="alert is-helpful">
|
||||||
|
|
||||||
Para ver la aplicación de ejemplo que describe esta página, consulta el <live-example></live-example>.
|
For the sample app that this page describes, see the <live-example></live-example>.
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
||||||
## Crea un simulacro de héroe
|
## Create mock heroes
|
||||||
|
|
||||||
Primero, necesitarás algunos héroes para mostrar.
|
You'll need some heroes to display.
|
||||||
Eventualmente los obtendrá de un servidor de datos remoto. Por ahora, creará algunos _héroes simulados_ y pretenderá que provienen del servidor.
|
|
||||||
|
|
||||||
Crea un archivo llamado `mock-heroes.ts` en la carpeta `src/app/`.
|
Eventually you'll get them from a remote data server.
|
||||||
Define la constante `HEROES` como un conjunto de 10 héroes y expórtala.
|
For now, you'll create some _mock heroes_ and pretend they came from the server.
|
||||||
El archivo se verá así:
|
|
||||||
|
Create a file called `mock-heroes.ts` in the `src/app/` folder.
|
||||||
|
Define a `HEROES` constant as an array of ten heroes and export it.
|
||||||
|
The file should look like this.
|
||||||
|
|
||||||
<code-example path="toh-pt2/src/app/mock-heroes.ts" header="src/app/mock-heroes.ts"></code-example>
|
<code-example path="toh-pt2/src/app/mock-heroes.ts" header="src/app/mock-heroes.ts"></code-example>
|
||||||
|
|
||||||
## Mostrar Héroes
|
## Displaying heroes
|
||||||
|
|
||||||
Abre el archivo de clase `HeroesComponent` e importe el mock `HEROES`.
|
Open the `HeroesComponent` class file and import the mock `HEROES`.
|
||||||
|
|
||||||
<code-example path="toh-pt2/src/app/heroes/heroes.component.ts" region="import-heroes" header="src/app/heroes/heroes.component.ts (import HEROES)">
|
<code-example path="toh-pt2/src/app/heroes/heroes.component.ts" region="import-heroes" header="src/app/heroes/heroes.component.ts (import HEROES)">
|
||||||
</code-example>
|
</code-example>
|
||||||
|
|
||||||
En el mismo archivo (clase `HeroesComponent`), define una propiedad de componente llamada `heroes` para exponer el array HEROES para la vinculación.
|
In the same file (`HeroesComponent` class), define a component property called `heroes` to expose the `HEROES` array for binding.
|
||||||
|
|
||||||
<code-example path="toh-pt2/src/app/heroes/heroes.component.ts" header="src/app/heroes/heroes.component.ts" region="component">
|
<code-example path="toh-pt2/src/app/heroes/heroes.component.ts" header="src/app/heroes/heroes.component.ts" region="component">
|
||||||
</code-example>
|
</code-example>
|
||||||
|
|
||||||
### Enumerar héroes con `*ngFor`
|
### List heroes with `*ngFor`
|
||||||
|
|
||||||
Abre las Plantillas `HeroesComponent` y realiza los siguientes cambios:
|
Open the `HeroesComponent` template file and make the following changes:
|
||||||
|
|
||||||
* Agrega `<h2>` al principio
|
* Add an `<h2>` at the top,
|
||||||
* Agrega una lista HTML desordenada (`<ul>`) debajo de ella
|
* Below it add an HTML unordered list (`<ul>`)
|
||||||
* Inserta `<li>` dentro del `<ul>` que muestra la propiedad `hero`
|
* Insert an `<li>` within the `<ul>` that displays properties of a `hero`.
|
||||||
* Espolvoreé algunas clases CSS al estilo (agregaremos estilos CSS en breve)
|
* Sprinkle some CSS classes for styling (you'll add the CSS styles shortly).
|
||||||
|
|
||||||
Se parece a esto:
|
Make it look like this:
|
||||||
|
|
||||||
<code-example path="toh-pt2/src/app/heroes/heroes.component.1.html" region="list" header="heroes.component.html (heroes template)"></code-example>
|
<code-example path="toh-pt2/src/app/heroes/heroes.component.1.html" region="list" header="heroes.component.html (heroes template)"></code-example>
|
||||||
|
|
||||||
Esto muestra un héroe. Para enumerarlos a todos, agrega `*ngFor*` a `<li>` para iterar sobre la lista de héroes.
|
That shows one hero. To list them all, add an `*ngFor` to the `<li>` to iterate through the list of heroes:
|
||||||
|
|
||||||
<code-example path="toh-pt2/src/app/heroes/heroes.component.1.html" region="li">
|
<code-example path="toh-pt2/src/app/heroes/heroes.component.1.html" region="li">
|
||||||
</code-example>
|
</code-example>
|
||||||
|
|
||||||
[`*ngFor`](guide/built-in-directives#ngFor) es la directiva de _repetición_ de Angular.
|
The [`*ngFor`](guide/built-in-directives#ngFor) is Angular's _repeater_ directive.
|
||||||
|
It repeats the host element for each element in a list.
|
||||||
|
|
||||||
Esto repite el elemento host para cada elemento de la lista.
|
The syntax in this example is as follows:
|
||||||
|
|
||||||
La sintaxis para este ejemplo es:
|
* `<li>` is the host element.
|
||||||
|
* `heroes` holds the mock heroes list from the `HeroesComponent` class, the mock heroes list.
|
||||||
* `<li>` es un elemento host
|
* `hero` holds the current hero object for each iteration through the list.
|
||||||
* `heroes` es una lista de clases `HeroesComponent` que contiene la lista de héroes simulados
|
|
||||||
* `hero` contiene el objeto héroe actual en una lista para cada ciclo
|
|
||||||
|
|
||||||
<div class="alert is-important">
|
<div class="alert is-important">
|
||||||
|
|
||||||
No olvides el asterisco (*) antes del `ngFor`. Esta es una parte importante de la sintaxis.
|
Don't forget the asterisk (*) in front of `ngFor`. It's a critical part of the syntax.
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
Actualiza tu navegador para ver la lista de héroes.
|
After the browser refreshes, the list of heroes appears.
|
||||||
|
|
||||||
{@a styles}
|
{@a styles}
|
||||||
|
|
||||||
### Agregar estilo a los héroes
|
### Style the heroes
|
||||||
|
|
||||||
La lista de héroes debe ser atractiva y visualmente prominente cuando el usuario coloca el cursor y selecciona un héroe de la lista.
|
The heroes list should be attractive and should respond visually when users
|
||||||
|
hover over and select a hero from the list.
|
||||||
|
|
||||||
En el [Primer tutorial](tutorial/toh-pt0#app-wide-styles), configuro el estilo básico de toda la aplicación en `styles.css`.
|
In the [first tutorial](tutorial/toh-pt0#app-wide-styles), you set the basic styles for the entire application in `styles.css`.
|
||||||
|
That stylesheet didn't include styles for this list of heroes.
|
||||||
|
|
||||||
No incluí el estilo de la lista de héroes en esta hoja de estilo.
|
You could add more styles to `styles.css` and keep growing that stylesheet as you add components.
|
||||||
|
|
||||||
Puedes agregar más estilos a `styles.css` y seguir expandiendo esa hoja de estilo a medida que agrega componentes
|
You may prefer instead to define private styles for a specific component and keep everything a component needs— the code, the HTML,
|
||||||
|
and the CSS —together in one place.
|
||||||
|
|
||||||
Es posible que prefieras definir un estilo privado para un componente en particular y mantener todo lo que el componente necesita —
|
This approach makes it easier to re-use the component somewhere else
|
||||||
código, HTML, CSS— en un solo lugar.
|
and deliver the component's intended appearance even if the global styles are different.
|
||||||
|
|
||||||
Este enfoque facilita la reutilización del componente en otro lugar y aún así proporciona al componente la apariencia deseada, incluso cuando los estilos aplicados globalmente son diferentes.
|
You define private styles either inline in the `@Component.styles` array or
|
||||||
|
as stylesheet file(s) identified in the `@Component.styleUrls` array.
|
||||||
|
|
||||||
Los estilos privados se definen en línea dentro de la matriz `@Component.styles` o como un archivo de hoja de estilo identificado en una matriz particular `@Component.styleUrls` como un archivo de hoja de estilo.
|
When the CLI generated the `HeroesComponent`, it created an empty `heroes.component.css` stylesheet for the `HeroesComponent`
|
||||||
|
and pointed to it in `@Component.styleUrls` like this.
|
||||||
Cuando la CLI crea un `HeroesComponent`, se crea un `heroes.component.css` vacío para el `HeroesComponent`.
|
|
||||||
`@Component.styleUrls` se señala de esta manera.
|
|
||||||
|
|
||||||
<code-example path="toh-pt2/src/app/heroes/heroes.component.ts" region="metadata"
|
<code-example path="toh-pt2/src/app/heroes/heroes.component.ts" region="metadata"
|
||||||
header="src/app/heroes/heroes.component.ts (@Component)">
|
header="src/app/heroes/heroes.component.ts (@Component)">
|
||||||
</code-example>
|
</code-example>
|
||||||
|
|
||||||
Abre `heroes.component.css` y pega el estilo privado para `HeroesComponent`.
|
Open the `heroes.component.css` file and paste in the private CSS styles for the `HeroesComponent`.
|
||||||
Puedes encontrarlos en la [Revisión del código final](#final-code-review) al final de esta guía.
|
You'll find them in the [final code review](#final-code-review) at the bottom of this guide.
|
||||||
|
|
||||||
<div class="alert is-important">
|
<div class="alert is-important">
|
||||||
|
|
||||||
`@Component` Los estilos y las hojas de estilo identificados en los metadatos se definen en un componente en particular.
|
Styles and stylesheets identified in `@Component` metadata are scoped to that specific component.
|
||||||
El estilo `heroes.component.css` solo se aplica a `HeroesComponent` y no afecta a otros HTML o HTML dentro de ningún otro componente.
|
The `heroes.component.css` styles apply only to the `HeroesComponent` and don't affect the outer HTML or the HTML in any other component.
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
## Maestro/Detalle
|
## Master/Detail
|
||||||
|
|
||||||
Cuando haces clic en un héroe en la lista **maestro**, el componente debe mostrar los **detalles** del héroe seleccionado en la parte inferior de la página.
|
When the user clicks a hero in the **master** list,
|
||||||
|
the component should display the selected hero's **details** at the bottom of the page.
|
||||||
|
|
||||||
En este capítulo, esperemos a que se haga clic en el elemento del héroe y luego actualiza los detalles del héroe.
|
In this section, you'll listen for the hero item click event
|
||||||
|
and update the hero detail.
|
||||||
|
|
||||||
### Agregar enlace de evento de clic
|
### Add a click event binding
|
||||||
|
|
||||||
Agrega el enlace de evento click a su `<li>` así:
|
Add a click event binding to the `<li>` like this:
|
||||||
|
|
||||||
<code-example path="toh-pt2/src/app/heroes/heroes.component.1.html" region="selectedHero-click" header="heroes.component.html (template excerpt)"></code-example>
|
<code-example path="toh-pt2/src/app/heroes/heroes.component.1.html" region="selectedHero-click" header="heroes.component.html (template excerpt)"></code-example>
|
||||||
|
|
||||||
Este es un ejemplo de la sintaxis de Angular [enlace de eventos](guide/event-binding) .
|
This is an example of Angular's [event binding](guide/event-binding) syntax.
|
||||||
|
|
||||||
Los paréntesis alrededor del `clic` le dicen a Angular que es un evento `clic` para el elemento `<li>`.
|
The parentheses around `click` tell Angular to listen for the `<li>` element's `click` event.
|
||||||
Cuando el usuario hace clic en `<li>`, Angular ejecuta la expresión `onSelect(hero)`.
|
When the user clicks in the `<li>`, Angular executes the `onSelect(hero)` expression.
|
||||||
|
|
||||||
En la siguiente sección, definiremos el método `onSelect()` en el `HeroesComponent` para mostrar los héroes definidos por las expresiones `*ngFor`.
|
|
||||||
|
|
||||||
### Agregar un controlador de eventos de clic
|
In the next section, define an `onSelect()` method in `HeroesComponent` to
|
||||||
|
display the hero that was defined in the `*ngFor` expression.
|
||||||
|
|
||||||
Cambia el nombre de la propiedad `hero` del componente a `selectedHero`, pero no la asignes todavía.
|
|
||||||
No hay _héroe seleccionado_ cuando se inicia la aplicación.
|
|
||||||
|
|
||||||
Agrega el método `onSelect()` de la siguiente manera y asigne el héroe en el que se hizo clic desde Plantillas al componente 'seleccionadoHero`.
|
### Add the click event handler
|
||||||
|
|
||||||
|
Rename the component's `hero` property to `selectedHero` but don't assign it.
|
||||||
|
There is no _selected hero_ when the application starts.
|
||||||
|
|
||||||
|
Add the following `onSelect()` method, which assigns the clicked hero from the template
|
||||||
|
to the component's `selectedHero`.
|
||||||
|
|
||||||
<code-example path="toh-pt2/src/app/heroes/heroes.component.ts" region="on-select" header="src/app/heroes/heroes.component.ts (onSelect)"></code-example>
|
<code-example path="toh-pt2/src/app/heroes/heroes.component.ts" region="on-select" header="src/app/heroes/heroes.component.ts (onSelect)"></code-example>
|
||||||
|
|
||||||
### Agregar una sección de detalles
|
### Add a details section
|
||||||
|
|
||||||
Actualmente, el componente Plantillas tiene una lista.
|
Currently, you have a list in the component template. To click on a hero on the list
|
||||||
Para hacer clic en un héroe en la lista para ver los detalles de ese héroe, necesita una sección de detalles para representarlo en Plantillas.
|
and reveal details about that hero, you need a section for the details to render in the
|
||||||
Agrega lo siguiente debajo de la sección de la lista de `heroes.component.html`.
|
template. Add the following to `heroes.component.html` beneath the list section:
|
||||||
|
|
||||||
<code-example path="toh-pt2/src/app/heroes/heroes.component.html" region="selectedHero-details" header="heroes.component.html (selected hero details)"></code-example>
|
<code-example path="toh-pt2/src/app/heroes/heroes.component.html" region="selectedHero-details" header="heroes.component.html (selected hero details)"></code-example>
|
||||||
|
|
||||||
Cuando actualizo el navegador, la aplicación está rota.
|
After the browser refreshes, the application is broken.
|
||||||
|
|
||||||
Abre y busca las herramientas de desarrollador de su navegador y busca un mensaje de error como este en la consola:
|
Open the browser developer tools and look in the console for an error message like this:
|
||||||
|
|
||||||
<code-example language="sh" class="code-shell">
|
<code-example language="sh" class="code-shell">
|
||||||
HeroesComponent.html:3 ERROR TypeError: no se puede leer la propiedad 'nombre' de undefined
|
HeroesComponent.html:3 ERROR TypeError: Cannot read property 'name' of undefined
|
||||||
</code-example>
|
</code-example>
|
||||||
|
|
||||||
### ¿Que pasó?
|
#### What happened?
|
||||||
|
|
||||||
Cuando inicia la aplicación, `selectedHero` es _intencionalmente_ indefinido`.
|
When the app starts, the `selectedHero` is `undefined` _by design_.
|
||||||
|
|
||||||
Los enlaces de expresión en Plantillas que se refieren a las propiedades de `selectedHero` - expresiones como` {{{selectedHero.name}} `deben _fallar_ porque el héroe seleccionado no existe, no.
|
Binding expressions in the template that refer to properties of `selectedHero`—expressions like `{{selectedHero.name}}`—_must fail_ because there is no selected hero.
|
||||||
|
|
||||||
### Reparemos-use _*ngIf_ para ocultar detalles vacíos
|
|
||||||
|
|
||||||
El componente solo debe mostrar detalles para el héroe seleccionado si `selectedHero` está presente.
|
#### The fix - hide empty details with _*ngIf_
|
||||||
|
|
||||||
|
|
||||||
|
The component should only display the selected hero details if the `selectedHero` exists.
|
||||||
|
|
||||||
|
Wrap the hero detail HTML in a `<div>`.
|
||||||
|
Add Angular's `*ngIf` directive to the `<div>` and set it to `selectedHero`.
|
||||||
|
|
||||||
Adjunta los detalles del héroe en HTML `<div>`.
|
|
||||||
Agrega la directiva angular `*ngIf` a su `<div>` y configúrelo en `selectedHero`.
|
|
||||||
|
|
||||||
<div class="alert is-important">
|
<div class="alert is-important">
|
||||||
|
|
||||||
No olvides el asterisco (*) antes del `ngIf`. Esta es una parte importante de la sintaxis.
|
Don't forget the asterisk (*) in front of `ngIf`. It's a critical part of the syntax.
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<code-example path="toh-pt2/src/app/heroes/heroes.component.html" region="ng-if" header="src/app/heroes/heroes.component.html (*ngIf)"></code-example>
|
<code-example path="toh-pt2/src/app/heroes/heroes.component.html" region="ng-if" header="src/app/heroes/heroes.component.html (*ngIf)"></code-example>
|
||||||
|
|
||||||
Actualiza su navegador y verá la lista de nombres nuevamente.
|
After the browser refreshes, the list of names reappears.
|
||||||
El área de detalles está en blanco.
|
The details area is blank.
|
||||||
Hace clic en un héroe en la lista de héroes para ver más detalles.
|
Click a hero in the list of heroes and its details appear.
|
||||||
La aplicación comenzó a funcionar nuevamente.
|
The app seems to be working again.
|
||||||
Los héroes se muestran en la lista, y los detalles del héroe seleccionado se muestran en la parte inferior de la página.
|
The heroes appear in a list and details about the clicked hero appear at the bottom of the page.
|
||||||
|
|
||||||
### Por qué esto funciona
|
|
||||||
|
|
||||||
Cuando `selectedHero` no está definido, `ngIf` elimina los detalles del héroe del DOM. No hay obligación de preocuparse por `selectedHero`.
|
#### Why it works
|
||||||
|
|
||||||
Cuando el usuario selecciona un héroe, `selectedHero` tiene un valor y `ngIf` inserta los detalles del héroe en el DOM.
|
When `selectedHero` is undefined, the `ngIf` removes the hero detail from the DOM. There are no `selectedHero` bindings to consider.
|
||||||
|
|
||||||
### Dar estilo a el héroe seleccionado
|
When the user picks a hero, `selectedHero` has a value and
|
||||||
|
`ngIf` puts the hero detail into the DOM.
|
||||||
|
|
||||||
Si todos los elementos `<li>` se parecen, es difícil identificar al _héroe seleccionado_ en la lista.
|
### Style the selected hero
|
||||||
|
|
||||||
Si el usuario hace clic en "Magneta", el héroe debe dibujarse con un color de fondo prominente como este:
|
It's difficult to identify the _selected hero_ in the list when all `<li>` elements look alike.
|
||||||
|
|
||||||
|
If the user clicks "Magneta", that hero should render with a distinctive but subtle background color like this:
|
||||||
|
|
||||||
<div class="lightbox">
|
<div class="lightbox">
|
||||||
<img src='generated/images/guide/toh/heroes-list-selected.png' alt="Selected hero">
|
<img src='generated/images/guide/toh/heroes-list-selected.png' alt="Selected hero">
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
El color del _héroe seleccionado_ es el trabajo de la clase CSS `.selected` en [el estilo que acaba de agregar](#styles).
|
That _selected hero_ coloring is the work of the `.selected` CSS class in the [styles you added earlier](#styles).
|
||||||
Simplemente aplica la clase `.selected` a `<li>` cuando el usuario hace clic.
|
You just have to apply the `.selected` class to the `<li>` when the user clicks it.
|
||||||
|
|
||||||
El [enlace de clase](guide/attribute-binding#class-binding)de Angular facilita la adición y eliminación de clases CSS condicionales.
|
The Angular [class binding](guide/attribute-binding#class-binding) makes it easy to add and remove a CSS class conditionally.
|
||||||
Simplemente agregue `[class.some-css-class] =" some-condition"` al elemento que desea decorar.
|
Just add `[class.some-css-class]="some-condition"` to the element you want to style.
|
||||||
|
|
||||||
Agrega el enlace `[class.selected]` al `<li>` en `HeroesComponent` Plantillas:
|
Add the following `[class.selected]` binding to the `<li>` in the `HeroesComponent` template:
|
||||||
|
|
||||||
<code-example path="toh-pt2/src/app/heroes/heroes.component.1.html" region="class-selected" header="heroes.component.html (toggle the 'selected' CSS class)"></code-example>
|
<code-example path="toh-pt2/src/app/heroes/heroes.component.1.html" region="class-selected" header="heroes.component.html (toggle the 'selected' CSS class)"></code-example>
|
||||||
|
|
||||||
Si el héroe de la fila actual es el mismo que de `selectedHero`, Angular agrega una clase CSS `selected`.Cuando los dos héroes son diferentes, Angular eliminará la clase.
|
When the current row hero is the same as the `selectedHero`, Angular adds the `selected` CSS class. When the two heroes are different, Angular removes the class.
|
||||||
|
|
||||||
El `<li>` completado se ve así:
|
The finished `<li>` looks like this:
|
||||||
|
|
||||||
<code-example path = "toh-pt2/src/app/heroes/heroes.component.html" region = "li" header = "heroes.component.html (elemento de lista hero)"> </code-example>
|
<code-example path="toh-pt2/src/app/heroes/heroes.component.html" region="li" header="heroes.component.html (list item hero)"></code-example>
|
||||||
|
|
||||||
{@a final-code-review}
|
{@a final-code-review}
|
||||||
|
|
||||||
## Revisión final del código
|
## Final code review
|
||||||
|
|
||||||
Aquí está el archivo de código en esta página que incluye el estilo `HeroesComponent`.
|
Here are the code files discussed on this page, including the `HeroesComponent` styles.
|
||||||
|
|
||||||
<code-tabs>
|
<code-tabs>
|
||||||
|
|
||||||
@ -226,12 +241,13 @@ Aquí está el archivo de código en esta página que incluye el estilo `HeroesC
|
|||||||
|
|
||||||
<code-pane header="src/app/heroes/heroes.component.css" path="toh-pt2/src/app/heroes/heroes.component.css">
|
<code-pane header="src/app/heroes/heroes.component.css" path="toh-pt2/src/app/heroes/heroes.component.css">
|
||||||
</code-pane>
|
</code-pane>
|
||||||
|
|
||||||
</code-tabs>
|
</code-tabs>
|
||||||
|
|
||||||
## Resumen
|
## Summary
|
||||||
|
|
||||||
* La aplicación "Tour de Héroes" muestra una lista de héroes en la pantalla Maestro / Detalle
|
* The Tour of Heroes app displays a list of heroes in a Master/Detail view.
|
||||||
* El usuario puede seleccionar un héroe y ver los detalles de ese héroe
|
* The user can select a hero and see that hero's details.
|
||||||
* Utilizó `*ngFor` para mostrar la lista
|
* You used `*ngFor` to display a list.
|
||||||
* Utilizó `*ngIf` para incluir o excluir condicionalmente bloques de HTML
|
* You used `*ngIf` to conditionally include or exclude a block of HTML.
|
||||||
* La clase de estilo CSS se puede cambiar con el enlace `class`
|
* You can toggle a CSS style class with a `class` binding.
|
||||||
|
@ -1,19 +1,19 @@
|
|||||||
# Agregar navegación en la aplicación con enrutamiento
|
# Agregar navegación en la aplicación con enrutamiento
|
||||||
|
|
||||||
Hay nuevos requisitos para la aplicación Tour de Héroes:
|
Hay nuevos requisitos para la aplicación Tour of Heroes:
|
||||||
|
|
||||||
* Agregar una vista de *Panel de control*.
|
* Agregar una vista de *Panel de control*.
|
||||||
* Agregar la capacidad de navegar entre las vistas *Héroes* y *Dashboard*.
|
* Agregue la capacidad de navegar entre las vistas *Heroes* y *Dashboard*.
|
||||||
* Cuando los usuarios hacen clic en el nombre de un héroe en cualquiera de las vistas, navegar a una vista detallada del héroe seleccionado.
|
* Cuando los usuarios hacen clic en el nombre de un héroe en cualquiera de las vistas, navega a una vista detallada del héroe seleccionado.
|
||||||
* Cuando los usuarios hacen clic en un *enlace profundo* en un correo electrónico, abrir la vista detallada de un héroe en particular.
|
* Cuando los usuarios hacen clic en un *enlace profundo* en un correo electrónico, abre la vista detallada de un héroe en particular.
|
||||||
|
|
||||||
<div class="alert is-helpful">
|
<div class="alert is-helpful">
|
||||||
|
|
||||||
Para ver la aplicación de ejemplo que describe esta página, consulta el <live-example></live-example>.
|
Para ver la aplicación de ejemplo que describe esta página, consulte el<live-example></live-example>.
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
Cuando hayas terminado, los usuarios podrán navegar por la aplicación de esta manera:
|
Cuando haya terminado, los usuarios podrán navegar por la aplicación de esta manera:
|
||||||
|
|
||||||
<div class="lightbox">
|
<div class="lightbox">
|
||||||
<img src='generated/images/guide/toh/nav-diagram.png' alt="View navigations">
|
<img src='generated/images/guide/toh/nav-diagram.png' alt="View navigations">
|
||||||
@ -35,7 +35,7 @@ Utiliza el CLI para generarlo.
|
|||||||
<div class="alert is-helpful">
|
<div class="alert is-helpful">
|
||||||
|
|
||||||
`--flat` coloca el archivo en `src/app` en lugar de en su propia carpeta. <br>
|
`--flat` coloca el archivo en `src/app` en lugar de en su propia carpeta. <br>
|
||||||
`--module=app` le dice a la CLI que lo registre en el arreglo de `importaciones` del `AppModule`.
|
`--module=app` le dice a la CLI que lo registre en la matriz de `importaciones` del `AppModule`.
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
El archivo generado se ve así:
|
El archivo generado se ve así:
|
||||||
@ -43,22 +43,23 @@ El archivo generado se ve así:
|
|||||||
<code-example path="toh-pt5/src/app/app-routing.module.0.ts" header="src/app/app-routing.module.ts (generated)">
|
<code-example path="toh-pt5/src/app/app-routing.module.0.ts" header="src/app/app-routing.module.ts (generated)">
|
||||||
</code-example>
|
</code-example>
|
||||||
|
|
||||||
Reemplázalo con lo siguiente:
|
Reemplácelo con lo siguiente:
|
||||||
|
|
||||||
<code-example path="toh-pt5/src/app/app-routing.module.1.ts" header="src/app/app-routing.module.ts (updated)">
|
<code-example path="toh-pt5/src/app/app-routing.module.1.ts" header="src/app/app-routing.module.ts (updated)">
|
||||||
</code-example>
|
</code-example>
|
||||||
|
|
||||||
Primero, `AppRoutingModule` importa `RouterModule` y `Routes` para que la aplicación pueda tener funcionalidad de enrutamiento. La siguiente importación, `HeroesComponent`, le dará al enrutador un lugar adonde ir una vez que configure las rutas.
|
Primero, `AppRoutingModule` importa `RouterModule` y `Routes` para que la aplicación pueda tener funcionalidad de enrutamiento. La siguiente importación, `HeroesComponent`, le dará al enrutador un lugar adonde ir una vez que configure las rutas.
|
||||||
|
|
||||||
Ten en cuenta que las referencias de CommonModule y el arreglo de declaraciones son innecesarias, por lo que ya no forman parte de `AppRoutingModule`. Las siguientes secciones explican el resto del `AppRoutingModule` con más detalle.
|
Ten en cuenta que las referencias de CommonModule y la matriz de declaraciones son innecesarias, por lo que no
|
||||||
|
parte más larga de `AppRoutingModule`. Las siguientes secciones explican el resto del `AppRoutingModule` con más detalle.
|
||||||
|
|
||||||
### Rutas
|
### Rutas
|
||||||
|
|
||||||
La siguiente parte del archivo es donde configuras tus rutas.
|
La siguiente parte del archivo es donde configura sus rutas.
|
||||||
Las *Rutas* le indican al enrutador qué vista mostrar cuando un usuario hace clic en un enlace o
|
*Rutas* le indican al enrutador qué vista mostrar cuando un usuario hace clic en un enlace o
|
||||||
pega una URL en la barra de direcciones del navegador.
|
pega una URL en la barra de direcciones del navegador.
|
||||||
|
|
||||||
Como `AppRoutingModule` ya importa `HeroesComponent`, puedes usarlo en el arreglo de `rutas`:
|
Como `AppRoutingModule` ya importa `HeroesComponent`, puedes usarlo en la matriz de `rutas`:
|
||||||
|
|
||||||
<code-example path="toh-pt5/src/app/app-routing.module.ts" header="src/app/app-routing.module.ts"
|
<code-example path="toh-pt5/src/app/app-routing.module.ts" header="src/app/app-routing.module.ts"
|
||||||
region="heroes-route">
|
region="heroes-route">
|
||||||
@ -67,7 +68,7 @@ Como `AppRoutingModule` ya importa `HeroesComponent`, puedes usarlo en el arregl
|
|||||||
Una `Ruta` típica de Angular tiene dos propiedades:
|
Una `Ruta` típica de Angular tiene dos propiedades:
|
||||||
|
|
||||||
* `path`: una cadena que coincide con la URL en la barra de direcciones del navegador.
|
* `path`: una cadena que coincide con la URL en la barra de direcciones del navegador.
|
||||||
* `component`: el componente que el enrutador debe crear al navegar a esta ruta.
|
* `componet`: el componente que el enrutador debe crear al navegar a esta ruta.
|
||||||
|
|
||||||
Esto le dice al enrutador que haga coincidir esa URL con `path: 'héroes'`
|
Esto le dice al enrutador que haga coincidir esa URL con `path: 'héroes'`
|
||||||
y mostrar el `HeroesComponent` cuando la URL sea algo como `localhost:4200/heroes`.
|
y mostrar el `HeroesComponent` cuando la URL sea algo como `localhost:4200/heroes`.
|
||||||
@ -76,7 +77,7 @@ y mostrar el `HeroesComponent` cuando la URL sea algo como `localhost:4200/heroe
|
|||||||
|
|
||||||
Los metadatos `@NgModule` inicializan el enrutador y lo hacen escuchar los cambios de ubicación del navegador.
|
Los metadatos `@NgModule` inicializan el enrutador y lo hacen escuchar los cambios de ubicación del navegador.
|
||||||
|
|
||||||
La siguiente línea agrega el `RouterModule` al arreglo `AppRoutingModule` de `importartaciones` y
|
La siguiente línea agrega el `RouterModule` a la matriz `AppRoutingModule` `importa` y
|
||||||
lo configura con las `rutas` en un solo paso llamando
|
lo configura con las `rutas` en un solo paso llamando
|
||||||
`RouterModule.forRoot()`:
|
`RouterModule.forRoot()`:
|
||||||
|
|
||||||
@ -91,7 +92,7 @@ lo configura con las `rutas` en un solo paso llamando
|
|||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
A continuación, `AppRoutingModule` exporta el `RouterModule` para que esté disponible en toda la aplicación.
|
A continuación, `AppRoutingModule` exporta `RouterModule` para que esté disponible en toda la aplicación.
|
||||||
|
|
||||||
<code-example path="toh-pt5/src/app/app-routing.module.ts" header="src/app/app-routing.module.ts (exports array)" region="export-routermodule">
|
<code-example path="toh-pt5/src/app/app-routing.module.ts" header="src/app/app-routing.module.ts (exports array)" region="export-routermodule">
|
||||||
</code-example>
|
</code-example>
|
||||||
@ -110,13 +111,13 @@ El `<router-outlet>` le dice al enrutador dónde mostrar las vistas enrutadas.
|
|||||||
<div class="alert is-helpful">
|
<div class="alert is-helpful">
|
||||||
|
|
||||||
El `RouterOutlet` es una de las directivas del enrutador que estuvo disponible para el `AppComponent`
|
El `RouterOutlet` es una de las directivas del enrutador que estuvo disponible para el `AppComponent`
|
||||||
porque `AppModule` importa `AppRoutingModule` que exportó `RouterModule`. El comando `ng generate` que ejecutaste al comienzo de este tutorial agregó esta importación debido a la marca `--module=app`. Si creaste manualmente `app-routing.module.ts` o usaste una herramienta que no sea la CLI para hacerlo, deberás importar `AppRoutingModule` a `app.module.ts` y agregarlo al arreglo de `importaciones` del `NgModule`.
|
porque `AppModule` importa `AppRoutingModule` que exportó `RouterModule`. El comando `ng generate` que ejecutó al comienzo de este tutorial agregó esta importación debido a la marca `--module=app`. Si creó manualmente `app-routing.module.ts` o usó una herramienta que no sea la CLI para hacerlo, deberá importar `AppRoutingModule` a `app.module.ts` y agregarlo a las `importaciones` matriz del `NgModule`.
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
#### Pruébalo
|
#### Pruébalo
|
||||||
|
|
||||||
Deberías seguir ejecutando este comando CLI.
|
Debería seguir ejecutando este comando CLI.
|
||||||
|
|
||||||
<code-example language="sh" class="code-shell">
|
<code-example language="sh" class="code-shell">
|
||||||
ng serve
|
ng serve
|
||||||
@ -129,14 +130,14 @@ La URL termina en `/`.
|
|||||||
La ruta de acceso a `HeroesComponent` es `/heroes`.
|
La ruta de acceso a `HeroesComponent` es `/heroes`.
|
||||||
|
|
||||||
Agrega `/heroes` a la URL en la barra de direcciones del navegador.
|
Agrega `/heroes` a la URL en la barra de direcciones del navegador.
|
||||||
Deberías ver la vista maestra / detalle de héroes.
|
Debería ver la vista maestra / detallada de héroes familiares.
|
||||||
|
|
||||||
{@a routerlink}
|
{@a routerlink}
|
||||||
|
|
||||||
## Agregar un enlace de navegación (`routerLink`)
|
## Agregar un enlace de navegación (`routerLink`)
|
||||||
|
|
||||||
Idealmente, los usuarios deberían poder hacer clic en un enlace para navegar en lugar de
|
Idealmente, los usuarios deberían poder hacer clic en un enlace para navegar en lugar de
|
||||||
pegar una URL de ruta en la barra de direcciones.
|
que pegar una URL de ruta en la barra de direcciones.
|
||||||
|
|
||||||
Agrega un elemento `<nav>` y, dentro de él, un elemento de ancla que, al hacer clic,
|
Agrega un elemento `<nav>` y, dentro de él, un elemento de ancla que, al hacer clic,
|
||||||
activa la navegación al `HeroesComponent`.
|
activa la navegación al `HeroesComponent`.
|
||||||
@ -159,7 +160,7 @@ La barra de direcciones se actualiza a `/heroes` y aparece la lista de héroes.
|
|||||||
|
|
||||||
<div class="alert is-helpful">
|
<div class="alert is-helpful">
|
||||||
|
|
||||||
Haz que este y los futuros enlaces de navegación se vean mejor agregando estilos CSS privados a `app.component.css`
|
Hace que este y los enlaces de navegación futuros se vean mejor agregando estilos CSS privados a `app.component.css`
|
||||||
como se indica en la [revisión final del código](#appcomponent) a continuación.
|
como se indica en la [revisión final del código](#appcomponent) a continuación.
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
@ -195,30 +196,30 @@ Reemplaza el contenido del archivo predeterminado en estos tres archivos de la s
|
|||||||
|
|
||||||
La _plantilla_ presenta una cuadrícula de enlaces de nombres de héroes.
|
La _plantilla_ presenta una cuadrícula de enlaces de nombres de héroes.
|
||||||
|
|
||||||
* El repetidor `*ngFor` crea tantos enlaces como hay en en el arreglo `heroes` del componente.
|
* El repetidor `* ngFor` crea tantos enlaces como hay en en el arreglo `heroes` del componente.
|
||||||
* Los enlaces están diseñados como bloques de colores por el `dashboard.component.css`.
|
* Los enlaces están diseñados como bloques de colores por el `dashboard.component.css`.
|
||||||
* Los enlaces no van a ninguna parte todavía, pero [lo harán en breve](#hero-details).
|
* Los enlaces no van a ninguna parte todavía, pero [lo harán en breve](#hero-details).
|
||||||
|
|
||||||
La _clase_ es similar a la clase `HeroesComponent`.
|
La _clase_ es similar a la clase `HeroesComponent`.
|
||||||
* Define una propiedad de arreglo de héroes.
|
* Define una propiedad de matriz de héroes.
|
||||||
* El constructor espera que Angular inyecte el `HeroService` en una propiedad privada de `heroService`.
|
* El constructor espera que Angular inyecte el `HeroService` en una propiedad privada de `heroService`.
|
||||||
* El método del ciclo de vida `ngOnInit()` llama a `getHeroes()`.
|
* El gancho del ciclo de vida `ngOnInit()` llama a `getHeroes()`.
|
||||||
|
|
||||||
Este `getHeroes()` devuelve la lista dividida de héroes en las posiciones 1 y 5, devolviendo solo cuatro de los mejores héroes (segundo, tercero, cuarto y quinto).
|
Este `getHeroes()` devuelve la lista dividida de héroes en las posiciones 1 y 5, devolviendo solo cuatro de los mejores héroes (segundo, tercero, cuarto y quinto).
|
||||||
|
|
||||||
<code-example path="toh-pt5/src/app/dashboard/dashboard.component.ts" header="src/app/dashboard/dashboard.component.ts" region="getHeroes">
|
<code-example path="toh-pt5/src/app/dashboard/dashboard.component.ts" header="src/app/dashboard/dashboard.component.ts" region="getHeroes">
|
||||||
</code-example>
|
</code-example>
|
||||||
|
|
||||||
### Agregar la ruta del dashboard
|
### Agregar la ruta del tablero(dashboard)
|
||||||
|
|
||||||
Para navegar hasta el dashboard, el enrutador necesita una ruta adecuada.
|
Para navegar hasta el tablero, el enrutador necesita una ruta adecuada.
|
||||||
|
|
||||||
Importa el `DashboardComponent` en el `AppRoutingModule`.
|
Importa el `DashboardComponent` en el `AppRoutingModule`.
|
||||||
|
|
||||||
<code-example path="toh-pt5/src/app/app-routing.module.ts" region="import-dashboard" header="src/app/app-routing.module.ts (import DashboardComponent)">
|
<code-example path="toh-pt5/src/app/app-routing.module.ts" region="import-dashboard" header="src/app/app-routing.module.ts (import DashboardComponent)">
|
||||||
</code-example>
|
</code-example>
|
||||||
|
|
||||||
Agrega una ruta al arreglo `AppRoutingModule.routes` que coincida con una ruta al `DashboardComponent`.
|
Agrega una ruta a la matriz `AppRoutingModule.routes` que coincida con una ruta al `DashboardComponent`.
|
||||||
|
|
||||||
<code-example path="toh-pt5/src/app/app-routing.module.ts" header="src/app/app-routing.module.ts" region="dashboard-route">
|
<code-example path="toh-pt5/src/app/app-routing.module.ts" header="src/app/app-routing.module.ts" region="dashboard-route">
|
||||||
</code-example>
|
</code-example>
|
||||||
@ -227,10 +228,10 @@ Agrega una ruta al arreglo `AppRoutingModule.routes` que coincida con una ruta a
|
|||||||
|
|
||||||
Cuando se inicia la aplicación, la barra de direcciones del navegador apunta a la raíz del sitio web.
|
Cuando se inicia la aplicación, la barra de direcciones del navegador apunta a la raíz del sitio web.
|
||||||
Eso no coincide con ninguna ruta existente, por lo que el enrutador no navega a ninguna parte.
|
Eso no coincide con ninguna ruta existente, por lo que el enrutador no navega a ninguna parte.
|
||||||
El espacio debajo del `<router-outlet>` está en blanco.
|
El espacio debajo de `<router-outlet>` está en blanco.
|
||||||
|
|
||||||
Para que la aplicación navegue al dashboard automáticamente, agrega la siguiente
|
Para que la aplicación navegue al panel de control automáticamente, agreaga la siguiente
|
||||||
ruta al arreglo `rutas`.
|
ruta a la matriz `AppRoutingModule.Routes`.
|
||||||
|
|
||||||
<code-example path="toh-pt5/src/app/app-routing.module.ts" header="src/app/app-routing.module.ts" region="redirect-route">
|
<code-example path="toh-pt5/src/app/app-routing.module.ts" header="src/app/app-routing.module.ts" region="redirect-route">
|
||||||
</code-example>
|
</code-example>
|
||||||
@ -240,13 +241,13 @@ Esta ruta redirige una URL que coincide completamente con la ruta vacía a la ru
|
|||||||
Después de que el navegador se actualiza, el enrutador carga el `DashboardComponent`
|
Después de que el navegador se actualiza, el enrutador carga el `DashboardComponent`
|
||||||
y la barra de direcciones del navegador muestra la URL `/dashboard`.
|
y la barra de direcciones del navegador muestra la URL `/dashboard`.
|
||||||
|
|
||||||
### Agregar enlace del dashboard al caparazón
|
### Agregar enlace del tablero al caparazón
|
||||||
|
|
||||||
El usuario debe poder navegar hacia adelante y hacia atrás entre
|
El usuario debe poder navegar hacia adelante y hacia atrás entre
|
||||||
`DashboardComponent` y `HeroesComponent` haciendo clic en los enlaces en el
|
`DashboardComponent` y `HeroesComponent` haciendo clic en los enlaces en el
|
||||||
área de navegación cerca de la parte superior de la página.
|
área de navegación cerca de la parte superior de la página.
|
||||||
|
|
||||||
Agrega un enlace de navegación del panel de control a la plantilla de caparazón `AppComponent`, justo encima del enlace *Héroes*.
|
Agrega un enlace de navegación del panel de control a la plantilla de caparazón `AppComponent`, justo encima del enlace *Heroes*.
|
||||||
|
|
||||||
<code-example path="toh-pt5/src/app/app.component.html" header="src/app/app.component.html">
|
<code-example path="toh-pt5/src/app/app.component.html" header="src/app/app.component.html">
|
||||||
</code-example>
|
</code-example>
|
||||||
@ -261,12 +262,12 @@ Por el momento, el `HeroDetailsComponent` solo es visible en la parte inferior d
|
|||||||
|
|
||||||
El usuario debería poder acceder a estos detalles de tres formas.
|
El usuario debería poder acceder a estos detalles de tres formas.
|
||||||
|
|
||||||
1. Haciendo clic en un héroe en el dashboard.
|
1. Haciendo clic en un héroe en el tablero.
|
||||||
1. Haciendo clic en un héroe de la lista de héroes.
|
1. Haciendo clic en un héroe de la lista de héroes.
|
||||||
1. Pegando una URL de "enlace profundo" en la barra de direcciones del navegador que identifica al héroe a mostrar.
|
1. Pegando una URL de "enlace profundo" en la barra de direcciones del navegador que identifica al héroe a mostrar.
|
||||||
|
|
||||||
En esta sección, habilitarás la navegación al `HeroDetailsComponent`
|
En esta sección, habilitará la navegación al `HeroDetailsComponent`
|
||||||
y lo liberarás del `HeroesComponent`.
|
y libérelo del `HeroesComponent`.
|
||||||
|
|
||||||
### Eliminar _detalles de héroe_ de `HeroesComponent`
|
### Eliminar _detalles de héroe_ de `HeroesComponent`
|
||||||
|
|
||||||
@ -276,21 +277,21 @@ reemplazando la vista de lista de héroes con la vista de detalles de héroe.
|
|||||||
La vista de lista de héroes ya no debería mostrar los detalles de los héroes como lo hace ahora.
|
La vista de lista de héroes ya no debería mostrar los detalles de los héroes como lo hace ahora.
|
||||||
|
|
||||||
Abre la plantilla `HeroesComponent` (`heroes/heroes.component.html`) y
|
Abre la plantilla `HeroesComponent` (`heroes/heroes.component.html`) y
|
||||||
elimina el elemento `<app-hero-detail>` de la parte inferior.
|
elimine el elemento `<app-hero-detail>` de la parte inferior.
|
||||||
|
|
||||||
Al hacer clic en un elemento de héroe ahora no hace nada.
|
Hacer clic en un elemento de héroe ahora no hace nada.
|
||||||
Lo [arreglarás en breve](#heroes-component-links) después de habilitar el enrutamiento al `HeroDetailComponent`.
|
Lo [arreglará en breve](#heroes-component-links) después de habilitar el enrutamiento al `HeroDetailComponent`.
|
||||||
|
|
||||||
### Agregar una ruta _detalle del héroe_
|
### Agregar una ruta _detalle del héroe_
|
||||||
|
|
||||||
Una URL como `~/detail/11` sería una buena URL para navegar a la vista *Hero Detail* del héroe cuyo `id` es `11`.
|
Una URL como `~/detail/11` sería una buena URL para navegar a la vista *Hero Detail* del héroe cuyo `id` es `11`.
|
||||||
|
|
||||||
Abre `AppRoutingModule` e importa `HeroDetailComponent`.
|
Abre `AppRoutingModule` e importe `HeroDetailComponent`.
|
||||||
|
|
||||||
<code-example path="toh-pt5/src/app/app-routing.module.ts" region="import-herodetail" header="src/app/app-routing.module.ts (import HeroDetailComponent)">
|
<code-example path="toh-pt5/src/app/app-routing.module.ts" region="import-herodetail" header="src/app/app-routing.module.ts (import HeroDetailComponent)">
|
||||||
</code-example>
|
</code-example>
|
||||||
|
|
||||||
Luego, agrega una ruta _parametrizada_ al arreglo de `rutas` que coincida con el patrón de ruta de la vista _detalle del héroe_.
|
Luego, agrega una ruta _parametrizada_ a la matriz `AppRoutingModule.routes` que coincida con el patrón de ruta de la vista _detalle del héroe_.
|
||||||
|
|
||||||
<code-example path="toh-pt5/src/app/app-routing.module.ts" header="src/app/app-routing.module.ts" region="detail-route">
|
<code-example path="toh-pt5/src/app/app-routing.module.ts" header="src/app/app-routing.module.ts" region="detail-route">
|
||||||
</code-example>
|
</code-example>
|
||||||
@ -307,7 +308,7 @@ En este punto, todas las rutas de aplicación están en su lugar.
|
|||||||
Los enlaces de héroe `DashboardComponent` no hacen nada en este momento.
|
Los enlaces de héroe `DashboardComponent` no hacen nada en este momento.
|
||||||
|
|
||||||
Ahora que el enrutador tiene una ruta a `HeroDetailComponent`,
|
Ahora que el enrutador tiene una ruta a `HeroDetailComponent`,
|
||||||
corrige los enlaces del héroe del dashboard para navegar a través de la ruta _parametrizada_ del dashboard.
|
Corrige los enlaces del héroe del tablero para navegar a través de la ruta del tablero _parameterized_.
|
||||||
|
|
||||||
<code-example
|
<code-example
|
||||||
path="toh-pt5/src/app/dashboard/dashboard.component.html"
|
path="toh-pt5/src/app/dashboard/dashboard.component.html"
|
||||||
@ -322,13 +323,13 @@ para insertar el `hero.id` de la iteración actual en cada
|
|||||||
{@a heroes-component-links}
|
{@a heroes-component-links}
|
||||||
### Enlaces de héroe de `HeroesComponent`
|
### Enlaces de héroe de `HeroesComponent`
|
||||||
|
|
||||||
Los elementos de héroe en el `HeroesComponent` son elementos `<li>` cuyos eventos de clic
|
Los elementos de héroe en el `HeroesComponent` son elementos` <li> `cuyos eventos de clic
|
||||||
están vinculados al método `onSelect()` del componente.
|
están vinculados al método `onSelect()` del componente.
|
||||||
|
|
||||||
<code-example path="toh-pt4/src/app/heroes/heroes.component.html" region="list" header="src/app/heroes/heroes.component.html (list with onSelect)">
|
<code-example path="toh-pt4/src/app/heroes/heroes.component.html" region="list" header="src/app/heroes/heroes.component.html (list with onSelect)">
|
||||||
</code-example>
|
</code-example>
|
||||||
|
|
||||||
Quita el `<li>` de nuevo a su `*ngFor`,
|
Quita el `<li>` de nuevo a su `* ngFor`,
|
||||||
envuelve la insignia y el nombre en un elemento de anclaje (`<a>`),
|
envuelve la insignia y el nombre en un elemento de anclaje (`<a>`),
|
||||||
y agrega un atributo `routerLink` al ancla que
|
y agrega un atributo `routerLink` al ancla que
|
||||||
es el mismo que en la plantilla del panel
|
es el mismo que en la plantilla del panel
|
||||||
@ -337,7 +338,7 @@ es el mismo que en la plantilla del panel
|
|||||||
</code-example>
|
</code-example>
|
||||||
|
|
||||||
Tendrás que arreglar la hoja de estilo privada (`heroes.component.css`) para hacer
|
Tendrás que arreglar la hoja de estilo privada (`heroes.component.css`) para hacer
|
||||||
que la lista tenga el mismo aspecto que antes.
|
la lista tiene el mismo aspecto que antes.
|
||||||
Los estilos revisados se encuentran en la [revisión final del código](#heroescomponent) al final de esta guía.
|
Los estilos revisados se encuentran en la [revisión final del código](#heroescomponent) al final de esta guía.
|
||||||
|
|
||||||
#### Eliminar código muerto (opcional)
|
#### Eliminar código muerto (opcional)
|
||||||
@ -353,7 +354,8 @@ Aquí está la clase después de podar el código muerto.
|
|||||||
|
|
||||||
## `HeroDetailComponent` enrutable
|
## `HeroDetailComponent` enrutable
|
||||||
|
|
||||||
Anteriormente, el padre `HeroesComponent` configuraba la propiedad `HeroDetailComponent.hero` y el `HeroDetailComponent` mostraba el héroe.
|
Anteriormente, el padre `HeroesComponent` configuraba el `HeroDetailComponent.hero`
|
||||||
|
propiedad y el `HeroDetailComponent` mostraba el héroe.
|
||||||
|
|
||||||
`HeroesComponent` ya no hace eso.
|
`HeroesComponent` ya no hace eso.
|
||||||
Ahora el enrutador crea el `HeroDetailComponent` en respuesta a una URL como `~/detail/11`.
|
Ahora el enrutador crea el `HeroDetailComponent` en respuesta a una URL como `~/detail/11`.
|
||||||
@ -361,8 +363,8 @@ Ahora el enrutador crea el `HeroDetailComponent` en respuesta a una URL como `~/
|
|||||||
El `HeroDetailComponent` necesita una nueva forma de obtener el héroe a mostrar.
|
El `HeroDetailComponent` necesita una nueva forma de obtener el héroe a mostrar.
|
||||||
Esta sección explica lo siguiente:
|
Esta sección explica lo siguiente:
|
||||||
|
|
||||||
* Obtener la ruta que lo creó
|
* Obtén la ruta que lo creó
|
||||||
* Extraer el `id` de la ruta
|
* Extrae el `id` de la ruta
|
||||||
* Adquirir el héroe con ese "id" del servidor a través de "HeroService"
|
* Adquirir el héroe con ese "id" del servidor a través de "HeroService"
|
||||||
|
|
||||||
Agrega las siguientes importaciones:
|
Agrega las siguientes importaciones:
|
||||||
@ -390,8 +392,8 @@ Lo usarás [más tarde](#goback) para volver a la vista que navegó aquí.
|
|||||||
|
|
||||||
### Extrae el parámetro de ruta `id`
|
### Extrae el parámetro de ruta `id`
|
||||||
|
|
||||||
En el `ngOnInit()` [método del ciclo de vida](guide/lifecycle-hooks#oninit)
|
En el `ngOnInit()` [gancho del ciclo de vida](guide/lifecycle-hooks#oninit)
|
||||||
llama a `getHero()` y defínelo de la siguiente manera.
|
llama a `getHero()` y defínalo de la siguiente manera.
|
||||||
|
|
||||||
<code-example path="toh-pt5/src/app/hero-detail/hero-detail.component.ts" header="src/app/hero-detail/hero-detail.component.ts" region="ngOnInit">
|
<code-example path="toh-pt5/src/app/hero-detail/hero-detail.component.ts" header="src/app/hero-detail/hero-detail.component.ts" region="ngOnInit">
|
||||||
</code-example>
|
</code-example>
|
||||||
@ -407,11 +409,11 @@ que es lo que debería ser un "id" de héroe.
|
|||||||
|
|
||||||
El navegador se actualiza y la aplicación se bloquea con un error del compilador.
|
El navegador se actualiza y la aplicación se bloquea con un error del compilador.
|
||||||
`HeroService` no tiene un método `getHero()`.
|
`HeroService` no tiene un método `getHero()`.
|
||||||
Agrégalo ahora.
|
Agréguelo ahora.
|
||||||
|
|
||||||
### Agregar `HeroService.getHero()`
|
### Agregar `HeroService.getHero ()`
|
||||||
|
|
||||||
Abre `HeroService` y agrega el siguiente método `getHero()` con el `id` después del método `getHeroes()`:
|
Abre `HeroService` y agrega el siguiente método `getHero()` con el `id` después del método `getHeroes ()`:
|
||||||
|
|
||||||
<code-example path="toh-pt5/src/app/hero.service.ts" region="getHero" header="src/app/hero.service.ts (getHero)">
|
<code-example path="toh-pt5/src/app/hero.service.ts" region="getHero" header="src/app/hero.service.ts (getHero)">
|
||||||
</code-example>
|
</code-example>
|
||||||
@ -424,18 +426,18 @@ Ten en cuenta las comillas invertidas (`) que definen un JavaScript
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
Como [`getHeroes()`](tutorial/toh-pt4#observable-heroservice),
|
Como [`getHeroes()`](tutorial/toh-pt4#observable-heroservice),
|
||||||
`getHero()` tiene una firma asincrónica.
|
`getHero()` tiene una firma asincrónica.
|
||||||
Devuelve un _mock hero_ como un `Observable`, usando la función RxJS `of()`.
|
Devuelve un _mock hero_ como un `Observable`, usando la función RxJS `of()`.
|
||||||
|
|
||||||
Podrás volver a implementar `getHero()` como una solicitud real de `Http`
|
Podrá volver a implementar `getHero()` como una solicitud real de `Http`
|
||||||
sin tener que cambiar el `HeroDetailComponent` que lo llama.
|
sin tener que cambiar el `HeroDetailComponent` que lo llama.
|
||||||
|
|
||||||
#### Pruébalo
|
#### Pruébalo
|
||||||
|
|
||||||
El navegador se actualiza y la aplicación vuelve a funcionar.
|
El navegador se actualiza y la aplicación vuelve a funcionar.
|
||||||
Puedes hacer clic en un héroe en el dashboard o en la lista de héroes y navegar hasta la vista de detalles de ese héroe.
|
Puedes hacer clic en un héroe en el tablero o en la lista de héroes y navegar hasta la vista de detalles de ese héroe.
|
||||||
|
|
||||||
Si pegas `localhost:4200/detail/11` en la barra de direcciones del navegador,
|
Si pega `localhost:4200/detail/11` en la barra de direcciones del navegador,
|
||||||
el enrutador navega a la vista detallada del héroe con `id: 11`," Dr Nice ".
|
el enrutador navega a la vista detallada del héroe con `id: 11`," Dr Nice ".
|
||||||
|
|
||||||
{@a goback}
|
{@a goback}
|
||||||
@ -443,8 +445,8 @@ el enrutador navega a la vista detallada del héroe con `id: 11`," Dr Nice ".
|
|||||||
### Encuentra el camino de regreso
|
### Encuentra el camino de regreso
|
||||||
|
|
||||||
Al hacer clic en el botón Atrás del navegador,
|
Al hacer clic en el botón Atrás del navegador,
|
||||||
puedes volver a la lista de héroes o la vista del panel,
|
puede volver a la lista de héroes o la vista del panel,
|
||||||
dependiendo de cuál te envió a la vista detallada.
|
dependiendo de cuál le envió a la vista detallada.
|
||||||
|
|
||||||
Sería bueno tener un botón en la vista `HeroDetail` que pueda hacer eso.
|
Sería bueno tener un botón en la vista `HeroDetail` que pueda hacer eso.
|
||||||
|
|
||||||
@ -462,7 +464,7 @@ usando el servicio `Location` que [inyectaste previamente](#hero-detail-ctor).
|
|||||||
|
|
||||||
</code-example>
|
</code-example>
|
||||||
|
|
||||||
Actualiza el navegador y comienza a hacer clic.
|
Actualiza el navegador y comience a hacer clic.
|
||||||
Los usuarios pueden navegar por la aplicación, desde el panel hasta los detalles del héroe y viceversa,
|
Los usuarios pueden navegar por la aplicación, desde el panel hasta los detalles del héroe y viceversa,
|
||||||
de la lista de héroes al mini detalle a los detalles del héroe y de regreso a los héroes nuevamente.
|
de la lista de héroes al mini detalle a los detalles del héroe y de regreso a los héroes nuevamente.
|
||||||
|
|
||||||
@ -559,11 +561,11 @@ Aquí están los archivos de código discutidos en esta página.
|
|||||||
|
|
||||||
## Resumen
|
## Resumen
|
||||||
|
|
||||||
* Agregaste el enrutador Angular para navegar entre diferentes componentes.
|
* Agregó el enrutador Angular para navegar entre diferentes componentes.
|
||||||
* Convertiste el `AppComponent` en un caparazón de navegación con enlaces `<a>`y un `<router-outlet>`.
|
* Convirtió el `AppComponent` en un caparazón de navegación con enlaces `<a>`y un `<router-outlet>`.
|
||||||
* Configuraste el enrutador en un `AppRoutingModule`
|
* Configuró el enrutador en un `AppRoutingModule`
|
||||||
* Definiste rutas simples, una ruta de redireccionamiento y una ruta parametrizada.
|
* Definió rutas simples, una ruta de redireccionamiento y una ruta parametrizada.
|
||||||
* Usaste la directiva `routerLink` en elementos de anclaje.
|
* Usó la directiva `routerLink` en elementos de anclaje.
|
||||||
* Refactorizaste una vista maestra/detallada estrechamente acoplada en una vista de detalle enrutada.
|
* Refactorizó una vista maestra/detallada estrechamente acoplada en una vista de detalle enrutada.
|
||||||
* Usaste parámetros de enlace del enrutador para navegar a la vista detallada de un héroe seleccionado por el usuario.
|
* Usó parámetros de enlace del enrutador para navegar a la vista detallada de un héroe seleccionado por el usuario.
|
||||||
* Compartiste el "HeroService" entre varios componentes.
|
* Compartió el "HeroService" entre varios componentes.
|
||||||
|
@ -20,7 +20,7 @@ describe('site App', function() {
|
|||||||
expect(browser.getTitle()).toBe('Angular');
|
expect(browser.getTitle()).toBe('Angular');
|
||||||
|
|
||||||
page.click(page.getTopMenuLink('features'));
|
page.click(page.getTopMenuLink('features'));
|
||||||
expect(browser.getTitle()).toBe('Angular - FUNCIONALIDADES Y VENTAJAS');
|
expect(browser.getTitle()).toBe('Angular - FUNCIONALIDADES & VENTAJAS');
|
||||||
|
|
||||||
page.click(page.homeLink);
|
page.click(page.homeLink);
|
||||||
expect(browser.getTitle()).toBe('Angular');
|
expect(browser.getTitle()).toBe('Angular');
|
||||||
|
Loading…
x
Reference in New Issue
Block a user