Angular 16 | Lendo parâmetros de rotas com Input() de maneira explícita

Uma das mudanças que o Angular trouxe nesta última versão foi a possibilidade de obter os dados da rota utilizando o decorator @Input(). Porém isso gerou uma discussão na comunidade:
Pode haver confusão no entendimento da finalidade do @Input?
A seguir vamos entender a funcionalidade e aplicar uma mudança que tornará a visibilidade de @Input’s do Router mais clara.
Habilitando o uso do @Input no Router
Para utilizar a funcionalidade precisamos alterar o Router
adicionando a função withComponentInputBinding()
para aplicações standalone ou a propriedade bindToComponentInputs
para módulos:
const routes: Routes = [{ path: 'page/:id', component: PageComponent, }, ];
bootstrapApplication(App, {
providers: [provideRouter(routes, withComponentInputBinding())],
});
@NgModule({
imports: [
RouterModule.forRoot(routes, {
bindToComponentInputs: true
})
],
})
export class AppModule {}
Obtendo parâmetros
A partir deste momento já conseguimos obter o id da rota page/:id
no PageComponent
através do @Input
:
@Component({
// ...
template: `<div>Page id = {{id}}</div>`,
})
export class PageComponent {
// Acessando rota /page/1 aplica valor "1" ao id.
@Input() id: string = '';
}
Porém ao visualizar o código acima sem o comentário não conseguimos dizer com certeza se esse @Input
é de uma rota ou é passado através de um componente pai.
O truque ⚡️
Para deixarmos claro qual é a finalidade do @Input
sem ter que adicionar comentários, podemos utilizar os alias @RouteParam
e @RouteQueryParam
:
import {
Component,
Input as RouteParam, // Para parâmetros /page/:id
Input as RouteQueryParam, // Para queryStrings /page/:id?name=home
} from '@angular/core';
@Component({
// ...
template: `<div>Page id = {{id}}</div>`,
})
export class PageComponent {
@RouteParam() id: string = '';
@RouteQueryParam() name: string = '';
}
Desta forma sempre que visualizarmos o código conseguimos entender qual é a fonte de dados da propriedade.
Exemplo de uso no StackBlitz:
Conclusão
A discussão levantada é válida e concordo que pode haver confusão no entendimento do uso do @Input. A forma apresentada vem para deixar mais perceptível o que o decorator está fazendo de fato. Dessa forma deixamos o código mais claro.