Vista previa de Angular 16: entrada de componente vinculada al enrutador

Ok, esta fue una de las características que más me entusiasmó porque a menudo me encuentro escribiendo mucho código para hacer algo muy simple: obtener un parámetro de enrutador. ¿De qué estoy hablando? Echemos un vistazo a un ejemplo.
Digamos que tenemos una aplicación web, y la aplicación web tiene la opción para un parámetro de enrutador como este https://myapp.com/contactForm?name=john&[email protected]
, y pasar estos parámetros nos permitiría completar automáticamente el formulario de contacto. ¿Cómo podemos lograr esto?
el viejo camino
Echemos un vistazo a cómo haríamos esto antes de Angular 16.
import { CommonModule } from '@angular/common';
import { Component, OnDestroy } from '@angular/core';
import {
FormControl,
FormGroup,
FormsModule,
ReactiveFormsModule,
} from '@angular/forms';
import { ActivatedRoute } from '@angular/router';
import { Subscription } from 'rxjs';
@Component({
selector: 'app-route-one',
standalone: true,
imports: [CommonModule, FormsModule, ReactiveFormsModule],
// templateUrl: './route-one.component.html',
template: `
<form [formGroup]="contactForm" class="contactForm" (submit)="submit()">
<input formControlName="firstName" type="text" />
<input formControlName="email" type="email" />
<textarea formControlName="comments"></textarea>
<button>Submit</button>
</form>
`,
styleUrls: ['./route-one.component.scss'],
})
export class RouteOneComponent implements OnDestroy {
contactForm = new FormGroup({
firstName: new FormControl(),
email: new FormControl(),
comments: new FormControl(),
});
private subscription = new Subscription();
constructor(private route: ActivatedRoute) {
this.subscription.add(
route.queryParams.subscribe((params) => {
const firstName = params['firstName'];
const email = params['email'];
const comments = params['comments'];
if (firstName) this.contactForm.controls.firstName.setValue(firstName);
if (email) this.contactForm.controls.email.setValue(email);
if (comments) this.contactForm.controls.comments.setValue(comments);
})
);
}
ngOnDestroy() {
this.subscription.unsubscribe();
}
submit() {
console.log(this.contactForm.value);
}
}
firstName
email
comments
el nuevo camino
Al momento de escribir esto, la versión actual de Angular 16 es 16.0.0-rc.2, y esa es la versión que usaré. Echemos un vistazo a la misma funcionalidad exacta. Antes de que podamos entrar en eso, hay una pequeña cosa que debe hacer antes de que esto funcione.
import { NgModule } from '@angular/core';
import { RouterModule, Routes } from '@angular/router';
const routes: Routes = [
{
path: 'route-one',
loadComponent: () =>
import('./route-one/route-one.component').then(
(m) => m.RouteOneComponent
),
},
];
@NgModule({
imports: [RouterModule.forRoot(routes, { bindToComponentInputs: true })],
exports: [RouterModule],
})
export class AppRoutingModule {}
import { CommonModule } from '@angular/common';
import { Component, Input, OnInit } from '@angular/core';
import {
FormControl,
FormGroup,
FormsModule,
ReactiveFormsModule,
} from '@angular/forms';
import { Subscription } from 'rxjs';
@Component({
selector: 'app-route-one',
standalone: true,
imports: [CommonModule, FormsModule, ReactiveFormsModule],
// templateUrl: './route-one.component.html',
template: `
<form [formGroup]="contactForm" class="contactForm" (submit)="submit()">
<input formControlName="firstName" type="text" />
<input formControlName="email" type="email" />
<textarea formControlName="comments"></textarea>
<button>Submit</button>
</form>
`,
styleUrls: ['./route-one.component.scss'],
})
export class RouteOneComponent implements OnInit {
@Input() firstName: string;
@Input() email: string;
@Input() comments: string;
contactForm = new FormGroup({
firstName: new FormControl(),
email: new FormControl(),
comments: new FormControl(),
});
ngOnInit(): void {
if (this.firstName)
this.contactForm.controls.firstName.setValue(this.firstName);
if (this.email) this.contactForm.controls.email.setValue(this.email);
if (this.comments)
this.contactForm.controls.comments.setValue(this.comments);
}
submit() {
console.log(this.contactForm.value);
}
}
Esto nos ayuda de 2 maneras
- es facil de leer
- Limpia el código para que no tengamos suscripciones que tengamos que administrar manualmente
Sin embargo, hay una pequeña advertencia en el primer punto, y esto se mencionó en el PR para obtener esta función.
El decorador de entrada ya se usa para pasar variables a su componente, por lo que esto puede enturbiar el agua entre la entrada del componente y los parámetros de consulta. La solución sugerida para esto es crear un nuevo nombre para el decorador que vincula los parámetros de consulta. Con suerte, esta solución se implementará antes del lanzamiento de Angular 16, pero supongo que ya veremos.
Si te ha gustado este artículo, ¡ven a mi sitio web para leer este artículo y más!