Anatomia e composição standalone
Um componente reúne uma classe TypeScript, um template e um selector através de metadata no decorator Component. O selector identifica o uso no template do consumidor; o nome da classe permite referenciar a implementação em TypeScript. No exemplo, OrderReview importa OrderLine e inclui-o no array imports do decorator.
As duas operações têm papéis diferentes. O import TypeScript permite usar a classe no ficheiro, enquanto a metadata disponibiliza a dependência ao template. Providers pertence a outro contrato, o de injeção de dependências.
Em Angular 22 os componentes são standalone por omissão, mas o exemplo declara essa opção explicitamente para tornar a premissa visível.
Interpolação e leitura reativa
A interpolação com chavetas duplas apresenta o resultado de uma expressão como texto. Para ler um signal, chama o getter: orders() obtém a lista e marked() obtém o booleano. A referência à função sem parênteses não é equivalente à leitura do valor.
Angular rastreia os signals lidos no template e pode atualizar a vista quando os valores mudam. O texto interpolado não deve ser confundido com uma declaração de evento: escrever toggle() numa interpolação avaliaria uma expressão de apresentação em vez de esperar por um clique. Mantém o cálculo da saída separado da intenção de alterar estado.
Propriedades, atributos e eventos
Parênteses retos ligam uma expressão a uma propriedade: [order] fornece o objeto ao input da linha e [disabled] num botão nativo escreve a propriedade DOM correspondente. Para um atributo sem a propriedade pretendida, usa o contrato attr, como [attr.role]; um valor null remove esse atributo.
Parênteses curvos declaram um listener, como (click)="reverse()". O argumento $event contém o evento nativo num listener nativo; nos outputs de componentes contém o payload emitido. Escolher a sintaxe depende do destino da informação, não apenas do nome que aparece entre aspas.
Controlo de fluxo com significado explícito
@if escolhe conteúdo conforme a expressão é truthy, com ramos alternativos quando necessário. @for repete conteúdo por item e disponibiliza contexto como $index e $count; @empty apresenta uma alternativa se a coleção não tiver itens. Não é um ciclo JavaScript com break e continue. @switch compara os valores estritamente e não tem fallthrough.
Assim, o número 2 não corresponde ao case da string "2". Antes de corrigir uma vista que escolhe o ramo errado, confirma o tipo do dado e o contrato da expressão em vez de adicionar casos redundantes ou coerções implícitas imaginadas.
Identidade de registos e reutilização de vistas
O exemplo usa track order.id porque cada encomenda tem identidade persistente e única. Ao inverter a ordem, a posição muda, mas o registo continua a ser o mesmo. Uma key aleatória ou um total repetido não cumpre esse contrato. $index pode ser adequado para uma coleção estática que nunca muda; não se deve generalizar essa premissa a uma lista reordenável.
Há ainda uma nuance documentada: @for dá prioridade à reutilização. Se uma propriedade usada em track mudar mas a referência do objeto continuar igual, Angular pode atualizar bindings da vista existente. Não importes de outro framework uma garantia de destruição e recriação sem a confirmar.
Ler o exemplo e diagnosticar a fronteira
OrderLine recebe order como input required e mantém marked como estado local. Toggle altera apenas essa marca. OrderReview cria um novo array ao inverter, preservando os objetos e ids.
Não há chamada a um serviço nem decisão de aprovação remota. Num defeito em que a marca aparece junto da encomenda errada, começa pelo id e pela expressão track. Num defeito em que o selector não é reconhecido, começa pelo imports do consumidor.
São problemas diferentes e exigem evidências diferentes. A avaliação pede interpretar o código e escolher decisões; não exige construir ou executar a aplicação.
Compatibilidade e resumo da composição
Um componente antigo pode declarar standalone: false e ser exportado por um NgModule. Nesse caso, o consumidor importa o módulo correspondente em vez de tratar a classe como standalone. Caminhos templateUrl e styleUrl são relativos ao diretório do componente, não à rota aberta no browser.
A base deste percurso é Angular 22, com TypeScript como pré-requisito conceptual separado. A versão de compilador de um projeto deve seguir a matriz Angular: a linha consultada para 22.0.x aceita TypeScript 6.0 e exclui 6.1. Estudar um percurso TypeScript mais recente não equivale a instalar essa versão numa aplicação incompatível.
// Reading example: Angular 22 standalone components; no bootstrap shown.
import {Component, input, signal} from '@angular/core';
type Order = {id: string; title: string};
@Component({
selector: 'order-line',
standalone: true,
template: `<p>{{ order().title }}: {{ marked() ? 'marked' : 'unmarked' }}</p>
<button type="button" (click)="toggle()">Toggle mark</button>`,
})
export class OrderLine {
readonly order = input.required<Order>();
readonly marked = signal(false);
toggle() { this.marked.update(value => !value); }
}
@Component({
selector: 'order-review',
standalone: true,
imports: [OrderLine],
template: `<button type="button" (click)="reverse()">Reverse order</button>
@for (order of orders(); track order.id) {
<order-line [order]="order" />
} @empty { <p>No orders</p> }`,
})
export class OrderReview {
readonly orders = signal<Order[]>([
{id: 'A7', title: 'First order'}, {id: 'B8', title: 'Second order'},
]);
reverse() { this.orders.update(rows => [...rows].reverse()); }
}OrderLine tem uma marca local por instância; OrderReview conserva ids únicos e inverte uma cópia do array. A binding fornece o objeto à linha e track order.id conserva a relação com o registo. A marca é apenas estado de interface: não grava aprovações nem altera o objeto recebido. O excerto não inclui bootstrap de uma aplicação.
Armadilhas comuns
Importar a classe em TypeScript e esquecer imports do componente; usar providers para dependências de template; ler um signal sem o chamar; usar a posição como identidade de dados reordenáveis; esperar fallthrough em @switch.
Tópicos relacionados: Signals, inputs e contratos de outputs · Injeção de dependências e ciclo de vida dos serviços · Testar comportamentos e limites de integração
A classe, metadata e template formam um contrato conjunto. Usa imports para dependências da vista, bindings apropriadas para cada interação e ids persistentes para dados que mudam de posição. Verifica a semântica documentada antes de usar track como uma política de reposição.
Referência: Standalone component composition · Angular 22; standalone components