• Skip to primary navigation
  • Skip to main content
  • Skip to footer

Codemotion Magazine

We code the future. Together

  • Discover
    • Events
    • Community
    • Partners
    • Become a partner
    • Hackathons
  • Magazine
    • Backend
    • Dev community
    • Carriere tech
    • Intelligenza artificiale
    • Interviste
    • Frontend
    • DevOps/Cloud
    • Linguaggi di programmazione
    • Soft Skill
  • Talent
    • Discover Talent
    • Jobs
    • Manifesto
  • Companies
  • For Business
    • EN
    • IT
    • ES
  • Sign in
ads

Davide PassafaroMarzo 12, 2024

Angular Signal Queries: leggi il DOM senza sforzo!

Frontend
Angular Signal Queries
facebooktwitterlinkedinreddit

Dopo l’introduzione dei Signal Inputs e dei Model Inputs, una nuova Signal API è disponibile nell’ecosistema Angular con la versione 17.2.0: le Signal Queries.

Recommended article
Maggio 26, 2025

10 consigli per diventare esperto di React!

Lucilla Tomassi

Lucilla Tomassi

Frontend

Le Signal Queries offrono un approccio alternativo alle query basate sui decoratori, ovvero @ViewChild, @ViewChildren, @ContentChild e @ContentChildren, fornendoci i risultati sotto forma di Signal.

Grazie alle query possiamo ricavare istanze di componenti, direttive, elementi DOM, e molto altro. Diamo uno sguardo a cosa è cambiato con le nuove Signal Queries.

⚠️ ATTENZIONE: le nuove Signal Queries sono ancora in developer preview ⚠️


View queries

Le view queries ci permettono di interagire direttamente con gli elementi presenti all’interno del template di un componente, anche detto view.

Entrambi i decoratori @ViewChild e @ViewChildren hanno ora una controparte Signal.

viewChild

Utilizzando la funzione viewChild possiamo ricavare l’istanza di un singolo elemento:

import { Component, ElementRef, Signal, viewChild } from '@angular/core';

@Component({
  selector: 'my-component',
  standalone: true,
  template: '<input #inputEl />',
})
export class MyComponent {
  inputElement: Signal<ElementRef | undefined> = viewChild('inputEl');
}
Code language: TypeScript (typescript)

Questa funzione accetta tutti i parametri accettati dal decoratore @ViewChild, e offre le stesse funzionalità, fornendo però il risultato sotto forma di Signal.

Quando una query non trova alcun risultato, il suo valore è undefined.
Questo caso è molto comune quando si utilizza il Control Flow con @if e @for. 
Proprio per questo motivo, il valore di un viewChild Signal ha come tipo ElementRef | undefined.

Nel caso in cui la presenza di almeno un elemento che rispetta la query è certa, e vogliamo rimuovere quel undefined, possiamo usare la funzione viewChild.required():

import { Component, ElementRef, Signal, viewChild } from '@angular/core';

@Component({
  selector: 'my-component',
  standalone: true,
  template: '<input #inputEl />',
})
export class MyComponent {
  inputElement: Signal<ElementRef> = viewChild.required('inputEl');
}
Code language: TypeScript (typescript)

Attenzione però, quando una query required non trova alcun risultato, Angular solleva un apposito errore:

viewChildren

Utilizzando la funzione viewChildren possiamo invece ricavare l’istanza di più elementi:

import { Component, ElementRef, Signal, viewChildren } from '@angular/core';

@Component({
  selector: 'my-component',
  standalone: true,
  template: `
    <input #inputEl />

    @if (showSecondInput) {
      <input #inputEl />
    }
  `,
})
export class MyComponent {
  showSecondInput = true;

  inputElementList: Signal<readonly ElementRef[]> = viewChildren('inputEl');
}
Code language: TypeScript (typescript)

Simile a quanto visto per viewChild, anche la funzione viewChildren accetta tutti i parametri accettati dal decoratore @ViewChildren, e offre le stesse funzionalità, fornendo anch’essa il risultato sotto forma di Signal.

Quando una query viewChildren non trova alcune risultato, il suo valore è un array vuoto. Questo garantisce che qualunque risultato sia sempre accessibile in sicurezza.


Content queries

Le content queries ci permettono di interagire direttamente con gli elementi presenti all’interno del contenuto di un componente.

Per contenuto di un componente si intende il gruppo di elementi passati tramite content projection, ovvero quando inseriamo alcuni elementi all’interno del tag del nostro componente, quando lo utilizziamo in un determinato template. Ad esempio:

<my-component>
  <span> Hello ;) </span>

  <input #inputEl />
</my-component>
Code language: HTML, XML (xml)

Nota: a parte per la sezione di template dove vengono svolte le query, le content queries API e le view queries API sono identiche.
Per questo, la prossima sezione dell’articolo riprende quasi interamente la precedente.

Similmente a quanto abbiamo visto con le view queries, anche @ContentChild e @ContentChildren hanno ora una controparte Signal.

contentChild

Utilizzando le funzioni contentChild e contentChild.required() possiamo ricavare l’istanza di un singolo elemento:

import { Component, contentChild, ElementRef, Signal } from '@angular/core';

@Component({
  selector: 'my-component',
  standalone: true,
  template: `
    <div>
      <ng-content />
    </div>
  `,
})
export class MyComponent {
  inputElement: Signal<ElementRef | undefined> = contentChild('inputEl');

  inputElementReq: Signal<ElementRef> = contentChild.required('inputEl');
}
Code language: TypeScript (typescript)

Anche qui, come già visto per la funzione viewChild, quando una required query non trova alcun risultato, Angular solleva un apposito errore:

contentChildren

Utilizzando la funzione contentChildren possiamo invece ricavare l’istanza di più elementi:

import { Component, contentChildren, ElementRef, Signal } from '@angular/core';

@Component({
  selector: 'my-component',
  standalone: true,
  template: `
    <div>
      <ng-content />
    </div>
  `,
})
export class MyComponent {
  inputElementList: Signal<readonly ElementRef[]> = contentChildren('inputEl');
}
Code language: TypeScript (typescript)

Similmente a quanto abbiamo visto con la funzione viewChildren, quando una query contentChildren non trova alcun risultato, il suo valore è un array vuoto.


Alcune regole a cui prestare attenzione

Le nuove funzioni, viewChild, viewChildren, contentChild e contentChildren, funzionano solamente se usate per inizializzare una proprietà di un componente o direttiva.

Utilizzandole diversamente non verrà generato alcun errore, ma la query non fornirà alcun risultato:

import { Component, ElementRef, Signal, viewChild } from '@angular/core';

@Component({
  selector: 'my-component',
  standalone: true,
  template: `
    <div #el></div>
  `,
})
export class MyComponent {
  el = viewChild('el'); // It works!

  constructor() {
    const myEl: Signal<undefined> = viewChild('el'); // No error
    console.log(myEl()); // undefined
  }
}
Code language: TypeScript (typescript)

Signal Queries vs Decorator Queries

Ottenere i risultati delle query sotto forma di Signal significa che possiamo comporli con altri Signal, utilizzando ad esempio le funzioni computed ed effect.

Questo è già di per se un grande vantaggio, poiché migliora la flessibilità e la funzionalità della nostra codebase, aprendo la strada inoltre a tutti i miglioramenti nella change detection che i Signals hanno portando all’interno framework.

In aggiunta, le Signal Queries offrono però altri vantaggi:

  • Tempi più prevedibili: i risultati delle query sono accessibili non appena sono disponibili;
  • Interfaccia API più semplice: ogni risultato della query viene fornito come Signal e le query con risultati multipli (viewChildren e contentChildren) restituiscono sempre un array definito;
  • Migliore tipizzazione: i casi con possibile risultato undefined sono ridotti, grazie alle funzioni required() e all’array predefinito per le query con risultati multipli;
  • Inferenza più accurata: TypeScript può dedurre tipi in modo più accurati quando viene utilizzato un type predicate o quando si esplicita un’opzione read;
  • Aggiornamenti lazy: come per tutti i Signals, Angular aggiorna i risultati delle query con una strategia lazy. Ciò significa che le operazioni di lettura vengono eseguite solo quando leggiamo esplicitamente i risultati della query.

Grazie per aver letto questo articolo 🙏

Mi piacerebbe avere qualche feedback quindi grazie in anticipo per qualsiasi commento. 👋

Infine, se ti è piaciuto davvero tanto, condividilo con la tua community. 👋😁

Codemotion Collection Background
Dalla community
Selezionati per te

Vuoi scoprire più articoli come questo? Dai un’occhiata alla collection Dalla community dove troverai sempre nuovi contenuti selezionati dal nostro team.

Share on:facebooktwitterlinkedinreddit

Tagged as:Angular

Davide Passafaro
Unpopular opinion: Scrum fa casino
Previous Post
Da sfida a opportunità: principi di leadership per trasformare il conflitto
Next Post

Footer

Discover

  • Events
  • Community
  • Partners
  • Become a partner
  • Hackathons

Magazine

  • Tech articles

Talent

  • Discover talent
  • Jobs

Companies

  • Discover companies

For Business

  • Codemotion for companies

About

  • About us
  • Become a contributor
  • Work with us
  • Contact us

Follow Us

© Copyright Codemotion srl Via Marsala, 29/H, 00185 Roma P.IVA 12392791005 | Privacy policy | Terms and conditions