Ushbu nutqning maqsadi Reaktiv shakllarning imkoniyatlarini ko'rsatish edi, xususan, ular juda ko'p tasdiqlash bilan murakkab shakllar bilan qanday ishlashadi.

Shakldagi har bir boshqaruv elementi (tanlash, kiritish, belgilash katakchalari va h.k.) valueChanges xususiyatiga ega bo‘lib, biz vaqt o‘tishi bilan o‘zgarishlarni kuzatish va funksional rejimda RxJS operatorlari yordamida qiymatlarni o‘zgartirish uchun obuna bo‘lishimiz mumkin. yo'l. Shunday qilib, shakl ma'lumotlar oqimi kabi ko'rib chiqiladi, bu erda har bir maydon kuzatilishi mumkin.

Keling, reaktiv shaklning misolini ko'rib chiqaylik:

import { Component, OnInit } from \'@angular/core\';
import { FormControl } from \'@angular/forms\';

@Component({
    selector: \'app-login-form\',
    template: `
      <input type="text" [formControl]="name">
    `
)
export class LoginComponent implements OnInit {
  name = new FormControl(\'name\');
  ngOnInit() {
     this.name.valueChanges.subscribe(data => console.log(data));
  }
}

Ko'rib turganingizdek, bizda FormControl sifatida e'lon qilingan xususiyat bor va biz uni ixtiyoriy qiymat bilan ishga tushirishimiz va uni shablondagi kiritish shakliga bog'lashimiz mumkin. Shunday qilib, ular doimo sinxronlashtiriladi. Shablondagi qiymat o‘zgarishlarini valueChange xususiyatiga aniq obuna bo‘lgan holda kuzatishim yoki komponentdagi qiymatni o‘zgartirish va uni shablonga aks ettirish uchun setValue usulidan foydalanishim mumkin. . U ikki tomonlama ma'lumotlarni bog'lash kabi ishlaydi.

Shablonga asoslangan shaklda har bir shakl elementi ngModel direktivasi bilan Model xususiyatiga (komponent mantig'i ichida) ulanadi. TPL shakllari asinxron bo'lishining sababi shu. ngModel direktivasi "o'zgarishlarni aniqlash ilovasining hayot tsikli" ga ulangan, shuning uchun HTML elementi va komponent o'rtasidagi qiymat voqealar tsiklining "belgisi" dan keyin yangilanadi.

RxJS kutubxonasi tufayli biz voqeani kuzatish va unga obuna bo'lish uchun fromEvent usulidan foydalanishimiz mumkin. Angular ViewChild dekoratoridan foydalanib va ​​Reaktiv shakllardan foydalanmasdan, biz DOM elementiga havolani olishimiz mumkin (masalan, getElementById) va kirish elementi ichidagi ma'lumotlarni manipulyatsiya qilish uchun RxJS operatorlaridan foydalanishimiz mumkin:

Albatta, siz RxJS-ni, hech bo'lmaganda map, filter, take, debounceTime va distinctUntilChanged kabi asosiy operatorlarni bilishingiz kerak.

Hozirgacha biz FormBuilder-dan FormControl, FormGroup va FormArray kabi Reaktiv shakllarning asosiy konstruktoridan foydalanmadik. Biz ularni FormBuilder bilan ishlatishimiz yoki oldingi misoldagi kabi yolg'iz foydalanishimiz mumkin.

Keyingi misol biroz qiyinroq, chunki biz formamizni yaratish va shakllarimizda yaxshi miqyoslilikka ega bo‘lish uchun FormGroup va FormBuilderni joriy qilamiz:

import { Component, OnInit } from \'@angular/core\';
import { FormControl, FormBuilder, FormGroup } from \'@angular/forms\';
 
@Component({
    selector: \'app-login-form\',
    template: `
    <form [formGroup]="loginForm" (ngSubmit)="submit()">
      <input type="text" [formControl]="username">
 
      <button [disabled]="loginForm.invalid">Login</button>
    </form>
  `
})
export class LoginComponent implements OnInit {
  loginForm: FormGroup;
  username = new FormControl(\'username\');
  constructor(private formBuilder: FormBuilder) {}
  ngOnInit() {
    this.loginForm = this.formBuilder.group({
      username: this.username
    });
    this.loginForm.valueChanges.subscribe(data => console.log(data));
  }
 
  submit() {
    console.log(this.loginForm.value);
  }
}

Angular sizga kamroq kod yozish imkonini beruvchi FormBuilder deb nomlangan xizmatni taqdim etadi. Uni ishlatish uchun biz uni “Burchaklarga bog'liqlik inyeksiyasi” orqali Komponent ichiga kiritishimiz kerak. Endi biz formalarimizni osongina yaratish uchun FormGroup-dan foydalanishimiz mumkin. FormGroup ichida biz kalit-qiymat juftligi ob'ektiga egamiz, bu erda kalit boshqaruv nomi, qiymat esa boshlang'ich qiymat, o'rnatilgan validatorlar va ba'zi maxsus tekshirgichlar kabi variantlar qatoridir.

Maxsus tekshiruvchi

Maxsus validator bu qoʻllaniladigan joyda boshqaruvni kirish sifatida qabul qiluvchi funksiya boʻlib, uning ichida biz baʼzi tekshirish kodlarini, masalan, Oddiy ifodaga mos kelishini boshqarishimiz mumkin.

Komponent mantig'ida bizda boshqaruv ma'lumotnomasini olishning uchta usuli mavjud:

  1. form.get('kompaniya')
  2. form.controls['kompaniya']
  3. shakl.nazorat.kompaniya

bu erda "forma" mening formamga havola. Ularning barchasi ekvivalentdir. Bu bizning HTML elementimizni komponentlar mantig'i ichida boshqarish uchun foydali bo'lishi mumkin.

Ichki shakl

O'rnatilgan shakllar guruhi bu biz birgalikda tasdiqlashimiz kerak bo'lgan kiritish elementlari guruhidir. Bu bizga ob'ektlar majmuasini yaratishga imkon beradi:

Ba'zi ishlaydigan misollar:

import { Component, OnInit } from \'@angular/core\';
import { FormBuilder, FormGroup, Validators } from \'@angular/forms\';
 
@Component({
    selector: \'app-login-form\',
    template: `
    <form [formGroup]="loginForm" (ngSubmit)="submit()">
      <input type="text" formControlName="username">

      <input type="password" formControlName="password">
      <button [disabled]="loginForm.invalid">Login</button>
    </form>
  `
})
export class LoginComponent implements OnInit {
  loginForm: FormGroup;
  constructor(private formBuilder: FormBuilder) {}
  ngOnInit() {
    this.loginForm = this.formBuilder.group({
      username: [\'\', [Validators.required, Validators.minLength(2)]],
      password: [\'\', [Validators.required, Validators.minLength(4)]],
    });
    this.loginForm.valueChanges.subscribe(data => console.log(data));
  }
 
  submit() {
    console.log(this.loginForm.value);
  }
}
import { Component, OnInit } from \'@angular/core\';
import { FormControl, FormBuilder, FormGroup, Validators } from \'@angular/forms\';
 
@Component({
    selector: \'app-login-form\',
    template: `
    <form [formGroup]="form" (ngSubmit)="send()">
      <input type="text" formControlName="username">
      <div formGroupName="carInfo">
       
        <input type="text" formControlName="model">
        <input type="number" formControlName="kw">
      </div>
      <i class="fa fa-check" *ngIf="form.get(\'carInfo\').valid && form.valid"></i>
      <button [disabled]="form.invalid">Login</button>
    </form>
  `
})
export class LoginComponent implements OnInit {
  form: FormGroup;
 
  constructor(private formBuilder: FormBuilder) {}
  ngOnInit() {
    this.form = this.formBuilder.group({
      username: [\'\', Validators.required],
      carInfo: this.formBuilder.group({
        model: [\'\', Validators.required],
        kw: [\'\', Validators.required],
      })
    });
    this.form.valueChanges.subscribe(data => console.log(data));
  }
 
  send() {
    console.log(this.form.value);
  }
}

Shuningdek, biz boshqa kiritish elementining qiymatiga asoslangan maydonni tasdiqlashimiz mumkin, masalan, parolga mos keladigan shakl maydonlari.

Har bir shakl guruhi ikkinchi parametrga ega bo'lishi mumkin, unda biz forma guruhining o'zi uchun maxsus tekshiruvchini belgilashimiz mumkin. Ushbu validator funksiya bo'lib, biz ikkita parol maydoniga havolani o'tkazishimiz va uning ichida mos keladigan tekshiruvni amalga oshirishimiz mumkin.

Shakllarimiz murakkablashganda, biz uni FormGroup-da yoki UI-ni Komponentlarda ajratishimiz mumkin. Shunday qilib, har bir FormGroup maxsus element bilan ifodalanishi mumkin:

Dinamik shakllar

FormArray yordamida biz elementni dinamik ravishda ko'rsata olamiz, bu FormGroupning variantidir, bunda ma'lumotlar FormGroupdagi kabi ob'ekt o'rniga massiv ichida ketma-ketlashtiriladi. Bu sizning dinamik shakllaringizda qancha boshqaruv mavjudligini bilmasangiz foydali bo'ladi.

Nihoyat, biz XHR REST chaqiruvidan kelib chiqishi mumkin bo'lgan JSON tuzilmasi asosida ish vaqtida shakl yaratishimiz mumkin. JSON tuzilishi yorliq, turi (kirish), validatorlar va boshqalar kabi xususiyatlarni o'z ichiga olishi mumkin.

Shablon ichida biz shablonga qaysi kiritish turini tanlash uchun ngFor direktivasi va ngSwitch dan foydalanamiz.

Ushbu yechim bilan bog'liq muammo shundaki, ngSwitch o'sishi mumkin, shuning uchun biz shakllar shablonini yaratishda foydalanishimiz mumkin bo'lgan komponentlarimiz uchun Xesh xaritasi yordamida boshqa yechimni aniqlashimiz mumkin. Har bir boshqaruv uchun biz komponent yaratishimiz mumkin. Shunday qilib, JavaScript kodida bizda JSON konfiguratsiyasini o'qish va ish vaqtida shakl boshqaruvini yaratish uchun tsikl mavjud, shablon uchun esa *ngFor va har bir iteratsiya uchun biz direktivadan foydalanishimiz mumkin. Boshqaruv konfiguratsiyasi asosida biz uchun to'g'ri komponentni yaratuvchi dynamicField.

Ko'rib turganimizdek, bu mavzu juda katta va biz bitta qog'ozda barcha jihatlarni qamrab ololmaymiz, lekin men sizning qiziqishingizni uyg'otdim deb umid qilaman.