Pratinjau Angular 16: Input Komponen Terikat ke Router

May 02 2023
Ok, ini adalah salah satu fitur yang paling membuat saya bersemangat karena saya sering mendapati diri saya menulis banyak kode untuk melakukan sesuatu yang sangat sederhana: dapatkan param router. Apa yang saya bicarakan? Mari kita lihat sebuah contoh.

Ok, ini adalah salah satu fitur yang paling membuat saya bersemangat karena saya sering mendapati diri saya menulis banyak kode untuk melakukan sesuatu yang sangat sederhana: dapatkan param router. Apa yang saya bicarakan? Mari kita lihat sebuah contoh.

Katakanlah kita memiliki aplikasi web, dan aplikasi web memiliki opsi untuk param router seperti ini https://myapp.com/contactForm?name=john&[email protected], dan meneruskan parameter ini akan memungkinkan kita mengisi formulir kontak secara otomatis. Bagaimana kita bisa mencapai ini?

Cara Lama

Mari intip bagaimana kita akan melakukan ini sebelum 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

Cara Baru

Pada saat penulisan ini, versi Angular 16 saat ini adalah 16.0.0-rc.2, dan itulah versi yang akan saya gunakan. Mari kita lihat fungsi yang sama persis. Sebelum kita membahasnya, ada satu hal kecil yang perlu Anda lakukan sebelum ini berhasil.

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);
  }
}

Ini membantu kami dalam 2 cara

  1. Mudah dibaca
  2. Itu membersihkan kode sehingga kami tidak memiliki langganan yang harus kami kelola secara manual

Ada peringatan kecil pada poin pertama, dan ini diangkat di PR untuk mendapatkan fitur ini.

Dekorator Input sudah digunakan untuk meneruskan variabel ke dalam komponen Anda, jadi ini dapat memperkeruh air antara input komponen dan parameter kueri. Perbaikan yang disarankan untuk ini adalah membuat nama baru untuk dekorator yang mengikat parameter kueri. Mudah-mudahan, perbaikan ini dilakukan sebelum rilis Angular 16, tapi saya rasa kita akan lihat nanti.

Jika Anda menikmati artikel ini, kunjungi situs web saya untuk membaca artikel ini dan banyak lagi!