Xem trước góc 16: Đầu vào thành phần được liên kết với bộ định tuyến

May 02 2023
Ok, đây là một trong những tính năng mà tôi thích thú nhất vì tôi thường thấy mình viết rất nhiều mã để làm một việc rất đơn giản: lấy thông số bộ định tuyến. Tôi đang nói về cái gì vậy? Hãy xem một ví dụ.

Ok, đây là một trong những tính năng mà tôi thích thú nhất vì tôi thường thấy mình viết rất nhiều mã để làm một việc rất đơn giản: lấy thông số bộ định tuyến. Tôi đang nói về cái gì vậy? Hãy xem một ví dụ.

Giả sử chúng ta có một ứng dụng web và ứng dụng web có tùy chọn cho thông số bộ định tuyến như thế này https://myapp.com/contactForm?name=john&[email protected]và việc chuyển các tham số này sẽ cho phép chúng tôi tự động điền vào biểu mẫu liên hệ. Làm thế nào chúng ta có thể thực hiện điều này?

con đường cũ

Hãy xem qua cách chúng tôi sẽ làm điều này trước 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

con đường mới

Tại thời điểm viết bài này, phiên bản hiện tại của Angular 16 là 16.0.0-rc.2 và đó là phiên bản tôi sẽ sử dụng. Chúng ta hãy xem chính xác chức năng tương tự. Trước khi chúng ta có thể đi sâu vào vấn đề đó, có một việc nhỏ bạn cần làm trước khi điều này hoạt động.

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

Điều này giúp chúng tôi theo 2 cách

  1. Thật dễ dàng để đọc
  2. Nó làm sạch mã để chúng tôi không có đăng ký mà chúng tôi phải quản lý thủ công

Tuy nhiên, có một cảnh báo nhỏ ở điểm đầu tiên và điều này đã được đưa ra trong PR để có được tính năng này.

Trình trang trí đầu vào đã được sử dụng để chuyển các biến vào thành phần của bạn, vì vậy điều này có thể làm lẫn lộn nước giữa đầu vào thành phần và tham số truy vấn. Cách khắc phục được đề xuất cho điều này là tạo một tên mới cho trình trang trí liên kết các tham số truy vấn. Hy vọng rằng bản sửa lỗi này được đưa ra trước khi phát hành Angular 16, nhưng tôi đoán chúng ta sẽ thấy.

Nếu bạn thích bài viết này, hãy đến trang web của tôi để đọc bài viết này và hơn thế nữa!