Visualização Angular 16: entrada de componente vinculada ao roteador

May 02 2023
Ok, esse foi um dos recursos que mais me entusiasmou, porque muitas vezes me pego escrevendo muito código para fazer algo muito simples: obter um parâmetro de roteador. Do que estou falando? Vamos dar uma olhada em um exemplo.

Ok, esse foi um dos recursos que mais me entusiasmou, porque muitas vezes me pego escrevendo muito código para fazer algo muito simples: obter um parâmetro de roteador. Do que estou falando? Vamos dar uma olhada em um exemplo.

Digamos que temos um aplicativo da web e o aplicativo da web tem a opção de um parâmetro de roteador como este https://myapp.com/contactForm?name=john&[email protected], e passar esses parâmetros nos permitiria preencher automaticamente o formulário de contato. Como podemos realizar isso?

à moda antiga

Vamos dar uma olhada em como faríamos isso antes do 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

O Novo Caminho

No momento em que escrevo isso, a versão atual do Angular 16 é 16.0.0-rc.2, e essa é a versão que usarei. Vamos dar uma olhada exatamente na mesma funcionalidade. Antes de entrarmos nisso, há uma pequena coisa que você precisa fazer antes que isso 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);
  }
}

Isso nos ajuda de 2 maneiras

  1. É fácil de ler
  2. Ele limpa o código para não termos assinaturas que precisamos gerenciar manualmente

Há uma pequena ressalva no primeiro ponto, porém, e isso foi criado no PR para obter esse recurso.

O decorador de entrada já é usado para passar variáveis ​​para o seu componente, então isso pode confundir a água entre a entrada do componente e os parâmetros de consulta. A correção sugerida para isso é criar um novo nome para o decorador que liga os parâmetros de consulta. Espero que essa correção seja implementada antes do lançamento do Angular 16, mas acho que veremos.

Se você gostou deste artigo, venha ao meu site para ler este artigo e muito mais!