Angular 16 미리보기: 라우터에 바인딩된 구성 요소 입력

May 02 2023
좋아, 라우터 매개 변수를 가져오는 매우 간단한 작업을 수행하기 위해 많은 코드를 작성하는 경우가 많기 때문에 이것은 내가 가장 흥분한 기능 중 하나였습니다. 내가 무슨 말을 하는 거지? 예를 살펴보겠습니다.

좋아, 라우터 매개 변수를 가져오는 매우 간단한 작업을 수행하기 위해 많은 코드를 작성하는 경우가 많기 때문에 이것은 내가 가장 흥분한 기능 중 하나였습니다. 내가 무슨 말을 하는 거지? 예를 살펴보겠습니다.

웹 앱이 있고 웹 앱에 이와 같은 라우터 매개변수에 대한 옵션이 있으며 https://myapp.com/contactForm?name=john&[email protected]이러한 매개변수를 전달하면 문의 양식을 자동으로 채울 수 있습니다. 이를 어떻게 달성할 수 있습니까?

옛날 방식

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

새로운 길

이 글을 쓰는 시점에서 Angular 16의 현재 버전은 16.0.0-rc.2이고 이것이 제가 사용할 버전입니다. 정확히 동일한 기능을 살펴보겠습니다. 시작하기 전에 이것이 작동하기 전에 수행해야 할 작은 작업이 하나 있습니다.

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

이것은 두 가지 방법으로 우리를 돕습니다

  1. 읽기 쉽다
  2. 수동으로 관리해야 하는 구독이 없도록 코드를 정리합니다.

그러나 첫 번째 사항에는 작은 주의 사항이 있으며, 이 기능을 사용하기 위해 PR에서 이 문제를 제기했습니다.

입력 데코레이터는 이미 구성 요소에 변수를 전달하는 데 사용되므로 구성 요소 입력과 쿼리 매개 변수 사이에 물이 흐려질 수 있습니다. 이에 대한 제안된 수정은 쿼리 매개변수를 바인딩하는 데코레이터의 새 이름을 만드는 것입니다. 바라건대, 이 수정 사항은 Angular 16이 출시되기 전에 적용되었지만 우리가 보게 될 것 같습니다.

이 기사가 마음에 드셨다면 제 웹사이트 로 오셔서 이 기사 등을 읽으십시오!