ค้นหาเว็บไซต์

TypeScript - วิธีการใช้สัญญาณกับ Angular Reactive Forms


ฉันมีฟอร์มที่ขับเคลื่อนด้วยเทมเพลตใน Angular 17 และฉันสามารถใช้สัญญาณกับฟอร์มของฉันแบบนี้:

@Component({
  selector: 'app-root',
  template: `
    <input [ngModel]='firstName()' (ngModelChange)="firstName.set($event)">
    <input [ngModel]='lastName()' (ngModelChange)="lastName.set($event)">
  `,
})
export class App {
  firstName= signal('first name');
  lastName= signal('last name');
} 

มีไอเดียไหมว่าฉันจะใช้สัญญาณของ Angular กับฟอร์มเชิงปฏิกิริยาได้อย่างไร?

คำตอบ #1

API ของฟอร์มแบบ Reactive ยังไม่รองรับสัญญาณ แต่มีคำขอฟีเจอร์ที่ได้รับการโหวตมากมาย: https://github.com/angular/angular/issues/53485 ดังนั้นเราสามารถคาดหวังว่าจะได้รับการสนับสนุนในเวอร์ชันอนาคตของ Angular ในระหว่างนี้ คุณสามารถใช้ toSignal() กับ observable valueChanges ได้ดังนี้:

myForm = new FormGroup({
  firstName: new FormControl(''),
});
firstName = toSignal(this.myForm.controls.firstName.valueChanges);
greetingText = computed(() => `Hello ${this.firstName()}!`);

ถ้าแบบฟอร์มของคุณมีค่าตั้งต้น คุณสามารถใช้ตัวเลือก initialValue ของ toSignal():

myForm = new FormGroup({
  firstName: new FormControl('John Doe'),
});
firstName = toSignal(
  this.myForm.controls.firstName.valueChanges,
  { initialValue: this.myForm.controls.firstName.value },
);
greetingText = computed(() => `Hello ${this.firstName()}!`);

โปรดทราบว่า toSignal() ปัจจุบันอยู่ในรุ่นพรีวิวสำหรับนักพัฒนาและอาจมีการเปลี่ยนแปลงก่อนที่จะมีความเสถียร

คำตอบ #2

เมื่อทำงานกับเทมเพลตที่ขับเคลื่อนโดยคุณสามารถทำได้เลย

@Component({
  selector: 'app-root',
  template: `
    <input [(ngModel)]='firstName'>
    <input [(ngModel)]='lastName'>
  `,
})
export class App {
  firstName= signal('first name');
  lastName= signal('last name');
} 

เมื่อทำงานกับ reactive จะมีการตั้งค่าโค้ดมากขึ้น แต่ที่นี่มีตัวอย่างโค้ด บทเรียน และการสาธิตบน stackblitz ที่ถูก fork แสดงวิธีการใช้งาน

คุณไม่สามารถใช้สัญญาณกับการควบคุมแต่ละรายการได้ แต่คุณสามารถแปลงการเปลี่ยนแปลงของการควบคุมเป็นสัญญาณและใช้มันร่วมกับการรวมของ computed และ effect เพื่อให้ได้หลายสถานการณ์

ฟอร์มเชิงปฏิกิริยา Angular (17+) + สัญญาณ & คอมโพเนนต์แบบสแตนด์อโลน

...
export class ProfileEditorComponent {
  profileForm!: FormGroup;
  firstnameSignal: Signal<any> | undefined;

  constructor(private fb: FormBuilder) {
    this.profileForm = this.fb.group({
      firstname: new FormControl('', Validators.required),
      lastname: new FormControl('', Validators.required),
      email: new FormControl('', Validators.required),
      gender: new FormControl('', Validators.required),
      country: new FormControl('', Validators.required),
    });

    // firstNameSignal is created using the toSignal function.
    // represents the value of the 'firstName' form control.
    // so now instead of manually subscribing to the valueChanges of the form control, we can directly use the signal in our template
    this.firstnameSignal = toSignal(
      this.profileForm.get('firstname')?.valueChanges.pipe(debounceTime(300)) ??
        of(null),
      {}
    );
  }

  onSubmit() {
    console.log('submited values: ', this.profileForm.value);
  }
}

Forked Stackblitz

บทความที่เกี่ยวข้อง