Solitamente è riferito al binding dei dati e al "legare" una proprietà di un oggetto HTML ad una proprietà di un oggetto JavaScript.
String Binding
Tutto ciò che sta all'interno di {{ }} viene valutato e convertito in una stringa
/* src/app/app.component.html */
/* text e path provengono dalla classe (componente) associata alla view.*/
<p>{{ text }}</p>
<img src="{{ path }}" />
Tutte le proprietà di un oggetto HTML possono essere messe in binding, tra [ ], con una proprietà del componente. La direzione è dall'esterno all'interno.
/* src/app/app.component.html */
<p [hidden]="true">{{ text }}</p>
<img [src]="path" />
Per valorizzare la proprietà si può utilizzare sia lo string binding, che l'attribute binding.
/* src/app/message.component.html */
<app-message message="This is a message"></app-message>
<app-message [message]="message"></app-message>
Tutti gli eventi definiti da HTML possono essere messi in binding, tra ( ), con un metodo del componente. È possibile accedere all'oggetto
evento passando $event
al metodo. La direzione è dall'interno
all'esterno.
/* src/app/app.component.html */
<p (click)="onClick()">{{ text }}</p>
<img
[src]="path" (dblclick)="onDbClick($event)" />
(focus)="mioMetodo()"
(blur)="mioMetodo()"
(submit)="mioMetodo()"
(scroll)="mioMetodo()"
(cut)="mioMetodo()"
(copy)="mioMetodo()"
(paste)="mioMetodo()"
(keydown)="mioMetodo()"
(keypress)="mioMetodo()"
(keyup)="mioMetodo()"
(mouseenter)="mioMetodo()"
(mousedown)="mioMetodo()"
(mouseup)="mioMetodo()"
(click)="mioMetodo()"
(dblclick)="mioMetodo()"
(drag)="mioMetodo()"
(dragover)="mioMetodo()"
(drop)="mioMetodo()"
Combina la possibilità di specificare una proprietà di un elemento e allo stesso tempo di restare in ascolto di un evento di modifica. È sempre meglio usare con cautela ngModel.
Operatore [()]
: banana in a box :)
/* src/app/app.component.html */
<app-message [(msg)]="msgString">{{ text }}</app-message>
<input [(ngModel)]="myInput" />
@Input()
e @Output()
sono due decoratori fondamentali in Angular che consentono la comunicazione tra componenti genitori
e figli
.
È un decorator da applicare ad una proprietà di un componente, per permettere il passaggio di dati dall'esterno verso l'interno.
Con @Input()
il valore della proprietà message
verrà passato dal genitore di questo elemento.
/* src/app/message.component.ts */
import { Component, Input } from
'@angular/core';
@Component({
...
})
export class MessageComponent {
@Input() message: string;
}
@Input() - Comunicazione da genitore a figlio:
Supponiamo di avere un componente genitore chiamato ParentComponent
e un componente figlio chiamato ChildComponent
. Vogliamo passare un valore dalla proprietà del componente genitore alla proprietà del componente figlio utilizzando @Input()
.
Passo 1: Definizione del Componente Genitore (ParentComponent)
import { Component } from '@angular/core';
@Component({
selector: 'app-parent',
template: `
<h2>Parent Component</h2>
<app-child [message]="parentMessage"></app-child>
`,
})
export class ParentComponent {
parentMessage = 'Messaggio dal genitore al figlio';
}
Passo 2: Definizione del Componente Figlio (ChildComponent)
import { Component, Input } from '@angular/core';
@Component({
selector: 'app-child',
template: '<p>Figlio dice: {{ message }}</p>',
})
export class ChildComponent {
@Input() message: string;
}
In questo esempio, stiamo utilizzando l'annotazione @Input()
nel componente figlio per indicare che la proprietà message
può essere passata dal componente genitore. Il componente genitore passa il valore attraverso il binding dell'attributo [message]
nell'elemento del componente figlio.
È un decorator da applicare ad un metodo di un componente, per permettere il passaggio di dati dall'interno verso l'esterno.
Il decorator @Output()
viene utilizzato su un
EventEmitter
che, di fatto, emette un nuovo evento al quale può restare in ascolto il genitore del componente.
La classe EventEmitter
è un Subject
(RxJS
)
/* src/app/message.component.ts */
import { Component, Output } from '@angular/core';
@Component({
...
})
export class MessageComponent {
@Output() onClose: EventEmitter<any> = new EventEmitter();
handleClose() {
this.onClose.emit();
}
}
@Output() - Comunicazione da figlio a genitore:
Ora, supponiamo che vogliamo inviare un messaggio dal componente figlio al componente genitore utilizzando @Output()
.
Passo 1: Definizione del Componente Genitore (ParentComponent)
import { Component } from '@angular/core';
@Component({
selector: 'app-parent',
template: `
<h2>Parent Component</h2>
<app-child (messageEvent)="receiveMessage($event)"></app-child>
<p>Genitore dice: {{ message }}</p>
`,
})
export class ParentComponent {
message: string;
receiveMessage($event: string) {
this.message = $event;
}
}
Passo 2: Definizione del Componente Figlio (ChildComponent)
import { Component, Output, EventEmitter } from '@angular/core';
@Component({
selector: 'app-child',
template: `
<h2>Child Component</h2>
<button (click)="sendMessage()">Invia Messaggio al Genitore</button>
`,
})
export class ChildComponent {
@Output() messageEvent = new EventEmitter<string>();
sendMessage() {
this.messageEvent.emit('Messaggio dal figlio al genitore');
}
}
In questo esempio, il componente figlio utilizza l'annotazione @Output()
per dichiarare l'evento messageEvent
. Quando viene cliccato il pulsante nel componente figlio, viene emesso l'evento con il messaggio specificato. Il componente genitore cattura questo evento utilizzando l'output binding (messageEvent)="receiveMessage($event)"
e chiama il metodo receiveMessage($event)
per gestire il messaggio ricevuto.
In sintesi, @Input()
consente al componente genitore di passare dati al componente figlio, mentre @Output()
consente al componente figlio di emettere eventi che possono essere catturati dal componente genitore. Questi decoratori sono fondamentali per la comunicazione efficace tra componenti in Angular.
Per catturare l'evento va utilizzata la sintassi event binding
.
/* src/app/message.component.html */
<app-message [message]="message" (onClose)="close()"></app-message>
In Angular, sia il Class Binding che lo Style Binding sono tecniche utilizzate per applicare dinamicamente classi CSS o stili a elementi HTML nel template, in base alle condizioni o ai valori delle proprietà del componente.
Class Binding:
Il Class Binding permette di applicare classi CSS a un elemento HTML in modo dinamico. Questo è utile quando desideri cambiare le classi di un elemento in base a determinate condizioni. Puoi usare la sintassi [class.nomeClasse]="condizione"
.
Ecco un esempio:
<div [class.error]="isError">Errore</div>
Nel tuo componente TypeScript, hai una variabile isError
che può essere true
o false
. Se isError
è true
, verrà applicata la classe CSS error
all'elemento div
.
Style Binding:
Lo Style Binding permette di applicare stili CSS a un elemento HTML in modo dinamico. Questo è utile quando desideri cambiare gli stili di un elemento in base a determinate condizioni. Puoi usare la sintassi [style.nomeStile]="valoreEspressione"
.
Ecco un esempio:
<p [style.color]="textColor">Questo testo è colorato</p>
Nel tuo componente TypeScript, hai una proprietà textColor
che contiene un valore come "red"
, "blue"
, etc. Questo valore viene utilizzato per applicare lo stile color
al paragrafo.
Differenze Chiave:
-
Class Binding: Utilizzato per applicare dinamicamente classi CSS a un elemento HTML in base alle condizioni. Puoi applicare più classi separate da spazi.
-
Style Binding: Utilizzato per applicare dinamicamente stili CSS a un elemento HTML in base alle condizioni. Puoi applicare stili individuali come
color
,background-color
, etc.
Entrambe queste tecniche sono potenti strumenti per creare interfacce dinamiche e reattive in Angular. Puoi combinarle con direttive strutturali come *ngIf
o *ngFor
per creare componenti che rispondono alle azioni dell'utente o ai cambiamenti dei dati.
Ecco un esempio pratico di come utilizzare il Class Binding in Angular per applicare classi CSS dinamicamente a un elemento HTML.
Supponiamo di avere un componente che rappresenta un messaggio e vogliamo applicare una classe CSS diversa a seconda del tipo di messaggio (ad esempio, un messaggio di errore, avviso o successo).
message.component.ts (Componente)
import { Component, Input } from '@angular/core';
@Component({
selector: 'app-message',
template: '<div [class]="messageType">{{ content }}</div>',
})
export class MessageComponent {
@Input() content: string;
@Input() type: string;
get messageType(): string {
switch (this.type) {
case 'error':
return 'error-message';
case 'warning':
return 'warning-message';
case 'success':
return 'success-message';
default:
return '';
}
}
}
styles.css (File CSS)
.error-message {
background-color: #ff3333;
color: white;
padding: 10px;
border: 1px solid #cc0000;
}
.warning-message {
background-color: #ffcc00;
color: black;
padding: 10px;
border: 1px solid #cc9900;
}
.success-message {
background-color: #33cc33;
color: white;
padding: 10px;
border: 1px solid #009900;
}
app.component.html (Template del Componente Principale)
<app-message content="Errore! Qualcosa è andato storto." type="error"></app-message>
<app-message content="Attenzione! Presta attenzione a questo messaggio." type="warning"></app-message>
<app-message content="Operazione completata con successo!" type="success"></app-message>
In questo esempio, abbiamo creato un componente MessageComponent
che accetta un contenuto e un tipo come input. Utilizzando il Class Binding, abbiamo applicato classi CSS diverse in base al tipo di messaggio. Ad esempio, se il tipo è "error", verrà applicata la classe error-message
, definendo così lo stile per i messaggi di errore.
L'uso del Class Binding in questo modo consente di ottenere un'applicazione più flessibile e dinamica, dove lo stile dei componenti può variare in base ai dati forniti.
Ecco un esempio pratico di come utilizzare lo Style Binding in Angular per applicare stili CSS dinamicamente a un elemento HTML.
Supponiamo di avere un componente che rappresenta un pulsante e vogliamo cambiare il colore del testo del pulsante in base a uno stato, ad esempio "attivo" o "disattivo".
button.component.ts (Componente)
import { Component, Input } from '@angular/core';
@Component({
selector: 'app-button',
template: '<button [style.color]="buttonColor">{{ label }}</button>',
})
export class ButtonComponent {
@Input() label: string;
@Input() isActive: boolean;
get buttonColor(): string {
return this.isActive ? 'green' : 'red';
}
}
app.component.html (Template del Componente Principale)
<app-button label="Pulsante Attivo" [isActive]="true"></app-button>
<app-button label="Pulsante Disattivo" [isActive]="false"></app-button>
In questo esempio, abbiamo creato un componente ButtonComponent
che accetta un'etichetta e uno stato di attivazione come input. Utilizzando lo Style Binding, abbiamo applicato lo stile color
al testo del pulsante in base allo stato dell'attivazione. Se lo stato è "attivo", il colore del testo del pulsante sarà verde; se è "disattivo", il colore sarà rosso.
Lo Style Binding è un modo efficace per applicare stili in modo dinamico, consentendo di creare interfacce più reattive e accattivanti.
Il Two-way binding (doppio legame o legame bidirezionale) è una funzionalità in Angular che consente di sincronizzare automaticamente i dati tra un componente e il suo template in entrambe le direzioni. In pratica, quando viene effettuata una modifica ai dati nel componente, questa modifica viene riflessa immediatamente nel template e viceversa, senza dover scrivere codice aggiuntivo per gestire gli eventi di input o output.
La caratteristica più comune di Two-way binding in Angular coinvolge l'utilizzo della direttiva [(ngModel)]
. Questa direttiva collega un controllo di input (come un campo di testo) a una proprietà del componente, consentendo sia la lettura che la scrittura dei dati.
Ecco un esempio di come funziona il Two-way binding con [(ngModel)]
:
<input [(ngModel)]="nome" placeholder="Inserisci il tuo nome">
<p>Ciao, {{ nome }}!</p>
Nel codice TypeScript del componente, avrai una proprietà chiamata nome
:
import { Component } from '@angular/core';
@Component({
selector: 'app-two-way-binding',
template: `
<input [(ngModel)]="nome" placeholder="Inserisci il tuo nome">
<p>Ciao, {{ nome }}!</p>
`,
})
export class TwoWayBindingComponent {
nome: string = '';
}
In questo esempio, ogni volta che l'utente inserisce qualcosa nell'input, il valore della proprietà nome
nel componente viene automaticamente aggiornato e riflesso nel paragrafo sottostante. Allo stesso modo, se cambi il valore di nome
nel componente, il valore dell'input verrà aggiornato di conseguenza.
Va notato che l'uso del Two-way binding può comportare una maggiore complessità e rendere il flusso di dati meno chiaro in alcuni casi. Pertanto, è consigliabile utilizzarlo in modo appropriato e preferire le tecniche di data flow unidirezionale (dalla classe del componente al template) in scenari più complessi.