Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 13 additions & 13 deletions adev-es/src/app/routing/sub-navigation-data.ts
Original file line number Diff line number Diff line change
Expand Up @@ -188,30 +188,30 @@ const DOCS_SUB_NAVIGATION_DATA: NavigationItem[] = [
],
},
{
label: 'Templates',
label: 'Plantillas',
children: [
{
label: 'Overview',
label: 'Visión general',
path: 'guide/templates',
contentPath: 'guide/templates/overview',
},
{
label: 'Binding dynamic text, properties and attributes',
label: 'Enlazar texto, propiedades y atributos dinámicos',
path: 'guide/templates/binding',
contentPath: 'guide/templates/binding',
},
{
label: 'Adding event listeners',
label: 'Agregando escuchadores de eventos',
path: 'guide/templates/event-listeners',
contentPath: 'guide/templates/event-listeners',
},
{
label: 'Two-way binding',
label: 'Enlance bidireccional',
path: 'guide/templates/two-way-binding',
contentPath: 'guide/templates/two-way-binding',
},
{
label: 'Control flow',
label: 'Flujo de control',
path: 'guide/templates/control-flow',
contentPath: 'guide/templates/control-flow',
},
Expand All @@ -221,37 +221,37 @@ const DOCS_SUB_NAVIGATION_DATA: NavigationItem[] = [
contentPath: 'guide/templates/pipes',
},
{
label: 'Slotting child content with ng-content',
label: 'Proyectar contenido hijo ng-content',
path: 'guide/templates/ng-content',
contentPath: 'guide/templates/ng-content',
},
{
label: 'Create template fragments with ng-template',
label: 'Crear fragmentos de plantilla con ng-template',
path: 'guide/templates/ng-template',
contentPath: 'guide/templates/ng-template',
},
{
label: 'Grouping elements with ng-container',
label: 'Agrupando elementos con ng-container',
path: 'guide/templates/ng-container',
contentPath: 'guide/templates/ng-container',
},
{
label: 'Variables in templates',
label: 'Variables en plantillas',
path: 'guide/templates/variables',
contentPath: 'guide/templates/variables',
},
{
label: 'Deferred loading with @defer',
label: 'Carga diferida con @defer',
path: 'guide/templates/defer',
contentPath: 'guide/templates/defer',
},
{
label: 'Expression syntax',
label: 'Sintaxis de expresiones',
path: 'guide/templates/expression-syntax',
contentPath: 'guide/templates/expression-syntax',
},
{
label: 'Whitespace in templates',
label: 'Espacios en blanco en plantillas',
path: 'guide/templates/whitespace',
contentPath: 'guide/templates/whitespace',
},
Expand Down
256 changes: 256 additions & 0 deletions adev-es/src/content/guide/templates/binding.en.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,256 @@
# Binding dynamic text, properties and attributes

In Angular, a **binding** creates a dynamic connection between a component's template and its data. This connection ensures that changes to the component's data automatically update the rendered template.

## Render dynamic text with text interpolation

You can bind dynamic text in templates with double curly braces, which tells Angular that it is responsible for the expression inside and ensuring it is updated correctly. This is called **text interpolation**.

```angular-ts
@Component({
template: `
<p>Your color preference is {{ theme }}.</p>
`,
...
})
export class AppComponent {
theme = 'dark';
}
```

In this example, when the snippet is rendered to the page, Angular will replace `{{ theme }}` with `dark`.

```angular-html
<!-- Rendered Output -->
<p>Your color preference is dark.</p>
```

Bindings that change over time should read values from [signals](/guide/signals). Angular tracks the signals read in the template, and updates the rendered page when those signal values change.

```angular-ts
@Component({
template: `
<!-- Does not necessarily update when `welcomeMessage` changes. -->
<p>{{ welcomeMessage }}</p>

<p>Your color preference is {{ theme() }}.</p> <!-- Always updates when the value of the `name` signal changes. -->
`
...
})
export class AppComponent {
welcomeMessage = "Welcome, enjoy this app that we built for you";
theme = signal('dark');
}
```

For more details, see the [Signals guide](/guide/signals).

Continuing the theme example, if a user clicks on a button that updates the `theme` signal to `'light'` after the page loads, the page updates accordingly to:

```angular-html
<!-- Rendered Output -->
<p>Your color preference is light.</p>
```

You can use text interpolation anywhere you would normally write text in HTML.

All expression values are converted to a string. Objects and arrays are converted using the value’s `toString` method.

## Binding dynamic properties and attributes

Angular supports binding dynamic values into object properties and HTML attributes with square brackets.

You can bind to properties on an HTML element's DOM instance, a [component](guide/components) instance, or a [directive](guide/directives) instance.

### Native element properties

Every HTML element has a corresponding DOM representation. For example, each `<button>` HTML element corresponds to an instance of `HTMLButtonElement` in the DOM. In Angular, you use property bindings to set values directly to the DOM representation of the element.

```angular-html
<!-- Bind the `disabled` property on the button element's DOM object -->
<button [disabled]="isFormValid()">Save</button>
```

In this example, every time `isFormValid` changes, Angular automatically sets the `disabled` property of the `HTMLButtonElement` instance.

### Component and directive properties

When an element is an Angular component, you can use property bindings to set component input properties using the same square bracket syntax.

```angular-html
<!-- Bind the `value` property on the `MyListbox` component instance. -->
<my-listbox [value]="mySelection()" />
```

In this example, every time `mySelection` changes, Angular automatically sets the `value` property of the `MyListbox` instance.

You can bind to directive properties as well.

```angular-html
<!-- Bind to the `ngSrc` property of the `NgOptimizedImage` directive -->
<img [ngSrc]="profilePhotoUrl()" alt="The current user's profile photo">
```

### Attributes

When you need to set HTML attributes that do not have corresponding DOM properties, such as SVG attributes, you can bind attributes to elements in your template with the `attr.` prefix.

```angular-html
<!-- Bind the `role` attribute on the `<ul>` element to the component's `listRole` property. -->
<ul [attr.role]="listRole()">
```

In this example, every time `listRole` changes, Angular automatically sets the `role` attribute of the `<ul>` element by calling `setAttribute`.

If the value of an attribute binding is `null`, Angular removes the attribute by calling `removeAttribute`.

### Text interpolation in properties and attributes

You can also use text interpolation syntax in properties and attributes by using the double curly brace syntax instead of square braces around the property or attribute name. When using this syntax, Angular treats the assignment as a property binding.

```angular-html
<!-- Binds a value to the `alt` property of the image element's DOM object. -->
<img src="profile-photo.jpg" alt="Profile photo of {{ firstName() }}" >
```

## CSS class and style property bindings

Angular supports additional features for binding CSS classes and CSS style properties to elements.

### CSS classes

You can create a CSS class binding to conditionally add or remove a CSS class on an element based on whether the bound value is [truthy or falsy](https://developer.mozilla.org/en-US/docs/Glossary/Truthy).

```angular-html
<!-- When `isExpanded` is truthy, add the `expanded` CSS class. -->
<ul [class.expanded]="isExpanded()">
```

You can also bind directly to the `class` property. Angular accepts three types of value:

| Description of `class` value | TypeScript type |
| ----------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------- |
| A string containing one or more CSS classes separated by spaces | `string` |
| An array of CSS class strings | `string[]` |
| An object where each property name is a CSS class name and each corresponding value determines whether that class is applied to the element, based on truthiness. | `Record<string, any>` |

```angular-ts
@Component({
template: `
<ul [class]="listClasses"> ... </ul>
<section [class]="sectionClasses()"> ... </section>
<button [class]="buttonClasses()"> ... </button>
`,
...
})
export class UserProfile {
listClasses = 'full-width outlined';
sectionClasses = signal(['expandable', 'elevated']);
buttonClasses = signal({
highlighted: true,
embiggened: false,
});
}
```

The above example renders the following DOM:

```angular-html
<ul class="full-width outlined"> ... </ul>
<section class="expandable elevated"> ... </section>
<button class="highlighted"> ... </button>
```

Angular ignores any string values that are not valid CSS class names.

When using static CSS classes, directly binding `class`, and binding specific classes, Angular intelligently combines all of the classes in the rendered result.

```angular-ts
@Component({
template: `<ul class="list" [class]="listType()" [class.expanded]="isExpanded()"> ...`,
...
})
export class Listbox {
listType = signal('box');
isExpanded = signal(true);
}
```

In the example above, Angular renders the `ul` element with all three CSS classes.

```angular-html
<ul class="list box expanded">
```

Angular does not guarantee any specific order of CSS classes on rendered elements.

When binding `class` to an array or an object, Angular compares the previous value to the current value with the triple-equals operator (`===`). You must create a new object or array instance when you modify these values in order for Angular to apply any updates.

If an element has multiple bindings for the same CSS class, Angular resolves collisions by following its style precedence order.

NOTE: Class bindings do not support space-separated class names in a single key. They also don't support mutations on objects as the reference of the binding remains the same. If you need one or the other, use the [ngClass](/api/common/NgClass) directive.

### CSS style properties

You can also bind to CSS style properties directly on an element.

```angular-html
<!-- Set the CSS `display` property based on the `isExpanded` property. -->
<section [style.display]="isExpanded() ? 'block' : 'none'">
```

You can further specify units for CSS properties that accept units.

```angular-html
<!-- Set the CSS `height` property to a pixel value based on the `sectionHeightInPixels` property. -->
<section [style.height.px]="sectionHeightInPixels()">
```

You can also set multiple style values in one binding. Angular accepts the following types of value:

| Description of `style` value | TypeScript type |
| ------------------------------------------------------------------------------------------------------------------------- | --------------------- |
| A string containing zero or more CSS declarations, such as `"display: flex; margin: 8px"`. | `string` |
| An object where each property name is a CSS property name and each corresponding value is the value of that CSS property. | `Record<string, any>` |

```angular-ts
@Component({
template: `
<ul [style]="listStyles()"> ... </ul>
<section [style]="sectionStyles()"> ... </section>
`,
...
})
export class UserProfile {
listStyles = signal('display: flex; padding: 8px');
sectionStyles = signal({
border: '1px solid black',
'font-weight': 'bold',
});
}
```

The above example renders the following DOM.

```angular-html
<ul style="display: flex; padding: 8px"> ... </ul>
<section style="border: 1px solid black; font-weight: bold"> ... </section>
```

When binding `style` to an object, Angular compares the previous value to the current value with the triple-equals operator (`===`). You must create a new object instance when you modify these values in order to Angular to apply any updates.

If an element has multiple bindings for the same style property, Angular resolves collisions by following its style precedence order.

## ARIA attributes

Angular supports binding string values to ARIA attributes.

```angular-html
<button type="button" [aria-label]="actionLabel()">
{{ actionLabel() }}
</button>
```

Angular writes the string value to the element’s `aria-label` attribute and removes it when the bound value is `null`.

Some ARIA features expose DOM properties or directive inputs that accept structured values (such as element references). Use standard property bindings for those cases. See the [accessibility guide](best-practices/a11y#aria-attributes-and-properties) for examples and additional guidance.
Loading