הבנת תבנית המפעל ב Angular

יישומים מודרניים דורשים לעתים קרובות צורות להסתגל לתפקידים שונים של משתמשים, schemas נתונים, או סביבות תצורה.בעצם יצירת FLT:0 מקרים עבור כל מוטציות מוביל קוד משוכפל, מקרים מתג שברירי, ולוגיקה אימות מסתבכת של המפעל מטפל זה על ידי מתן מנגנון מרכזי כדי ליצור אובייקטים המבוססים על סוג מוגדר או תצורה.

המפעל מערער את ההיגיון של ההרגעה, ולכן רכיבים כבר לא צריכים לדעת איזה סוג של כיתה מיידי או איך להרכיב את הפקדים.הפרדה זו של חששות הופכת את בסיס קוד מודולרי יותר, ניתן לבדוק, וניתן לדרג - במיוחד כאשר מספר סוגי הטופס גדל מעבר קומץ.התבנית מתאימה באופן טבעי למערכת ההזרקה של אנגולרי, ומאפשרת לרשום פונקציות למפעל כמו ספקי מזון הדרושים להם.

מדוע להשתמש בתבנית המפעל עבור צורות דינמיות?

Angular כבר מספק את ה-FLT:2 כדי להתמודד עם תרחישים מורכבים, אבל דפוס המפעל מבטל את לוח הרתח הרתחן הפרוצדורלי המלווה לעתים קרובות יצירת צורה.

  • (ב) ,0) ,הקוד שכפול (FLTRE:1) במקום לחזור על מבנים דומים (FLT:3) על פני רכיבים או שירותים, אתה מפתח את ההיגיון בשיטה במפעל אחד.כל סוג צורה בנוי על ידי כיתת בונה ייעודית, כך שאתה כותב את ההיגיון שלו רק פעם אחת.
  • (FLT:0) שימור יכולת תחזוקתיות (FLT:103) הוספת סוג חדש של צורה, פירושה יצירת מעמד בונה חדש ורישום אותו במפעל.
  • (FLT:0) תצורה גמישה של צורות צורה תצורה.FIRLT:1) המפעל יכול לקבל פרמטרים נוספים (למשל, הרשאות משתמשים, מקומי או דגלים תכונה) המשפיעים הכלולים או איך הם מאומתים.
  • (FLT:0) ,Supports דינמיים ממשקי משתמש.Builderph:1; כאשר סוג הטופס נקבע בריצה (לדוגמה, ממסד נתונים או פרמטר נתיב), המפעל הופך אותו טריוויאלי כדי להבהיר את הנכון (FLT:4 על זבוב).
  • (ב) ניתן להוכיח את ההסתברות של ה-FLT:1 כל בונה צורה ניתן להוכיח בנפרד.המפעל עצמו הופך למיפוי פשוט שניתן ללעג או לספוג במבחנים.

היתרונות האלה הם בעלי ערך במיוחד ביישומים ארגוניים אשר חייבים לתמוך בזרימות עבודה רבות, כל אחת עם סט של שדות משלה וחוקי אימות.

המונחים:

שלב 1: טופס Define Form Enumeration and Interfaces

התחל על ידי הגדרת קבוצה של סוגים של צורה.שימוש aum מונע הקלדוס ומספק חוזה ברור:

export enum FormType {
 Login = 'login',
 Registration = 'registration',
 Feedback = 'feedback',
 Contact = 'contact'
}

הבא, להגדיר ממשק שכל בונה הטופס ייישם.זה מבטיח שהמפעל יוכל לטפל בו פולימורפילי:

import { FormGroup } from '@angular/forms';

export interface FormBuilderInterface {
 build(config?: any): FormGroup;
}

פרמטר אופציונלי (FLT 7) מאפשר לבונים להתאים את הטופס מבוסס על נתונים בזמן ריצה, כגון ערכים טרום סינון או התאמת כללי אימות לתפקיד המשתמש.

שלב 2: יצירת יצרניות טפסים

כל בונה בטון יישם את ה-FLT:8 וחוזר בצורה נכונה (FLT:9 לדוגמה, בונה טופס כניסה עשוי להיראות כך:

import { FormBuilder, FormGroup, Validators } from '@angular/forms';

export class LoginFormBuilder implements FormBuilderInterface {
 private fb: FormBuilder;

 constructor() {
 this.fb = new FormBuilder();
 }

 build(): FormGroup {
 return this.fb.group({
 email: ['', [Validators.required, Validators.email]],
 password: ['', [Validators.required, Validators.minLength(6)]],
 rememberMe: [false]
 });
 }
}

בונה טופס רישום עשוי לכלול בקרה נוספת ואימות שדה הצלב:

export class RegistrationFormBuilder implements FormBuilderInterface {
 private fb: FormBuilder;

 constructor() {
 this.fb = new FormBuilder();
 }

 build(): FormGroup {
 const form = this.fb.group({
 firstName: ['', Validators.required],
 lastName: ['', Validators.required],
 email: ['', [Validators.required, Validators.email]],
 password: ['', [Validators.required, Validators.minLength(8)]],
 confirmPassword: ['', Validators.required]
 }, { validators: this.matchPasswords });

 return form;
 }

 private matchPasswords(group: FormGroup): { [key: string]: any } | null {
 const password = group.get('password')?.value;
 const confirm = group.get('confirmPassword')?.value;
 return password === confirm ? null : { mismatch: true };
 }
}

מבנה זה מקנה באופן נקי: כל בונה מתמקד רק בפרטים של הטופס שלו, ואתה יכול להשתמש בלוגיקה על ידי הצבת בונה או באמצעות פונקציות עוזר.

שלב 3: בניית המפעל

מעמד המפעל אחראי למיפוי סוג צורה של בונה המתאים שלו. יישום פשוט משתמש בהצהרת מתג או אובייקט מפה:

import { Injectable } from '@angular/core';
import { FormGroup } from '@angular/forms';
import { FormType } from './form-type.enum';
import { LoginFormBuilder } from './login-form.builder';
import { RegistrationFormBuilder } from './registration-form.builder';
import { FeedbackFormBuilder } from './feedback-form.builder';

@Injectable({ providedIn: 'root' })
export class FormFactory {
 private builders = new Map<FormType, FormBuilderInterface>();

 constructor() {
 // Register builders
 this.builders.set(FormType.Login, new LoginFormBuilder());
 this.builders.set(FormType.Registration, new RegistrationFormBuilder());
 this.builders.set(FormType.Feedback, new FeedbackFormBuilder());
 }

 createForm(type: FormType, config?: any): FormGroup {
 const builder = this.builders.get(type);
 if (!builder) {
 throw new Error(`No builder registered for form type: ${type}`);
 }
 return builder.build(config);
 }
}

איסוף מבנים בתוך הבונים הוא פשוט, אבל עבור יישומים גדולים יותר אתה יכול מעדיף להשתמש הזרקת התלות של אנגולרי כדי לספק בונה.

שלב 4: השתמש במפעל ב-Commonents

עם המפעל במקום, רכיבים יכולים לבקש מקרה טופס מבלי לדעת את פרטי הבנייה שלו.לדוגמה, מרכיב המטפל בסוגים מרובים של צורות המבוססות על פרמטר נתיב:

import { Component, OnInit } from '@angular/core';
import { FormGroup } from '@angular/forms';
import { FormFactory } from './form.factory';
import { FormType } from './form-type.enum';

@Component({
 selector: 'app-dynamic-form',
 template: `