Unlimited Plugins, WordPress themes, videos & courses! Unlimited asset downloads! From $16.50/m
Advertisement
  1. Code
  2. Angular
Code

Angular 4 में फॉर्म्स का परिचय: रिएक्टिव फॉर्म्स

by
Difficulty:BeginnerLength:LongLanguages:
This post is part of a series called Introduction to Forms in Angular 4.
Introduction to Forms in Angular 4: Template-Driven Forms
Introduction to Forms in Angular 4: Writing Custom Form Validators

Hindi (हिंदी) translation by Ashish Rampal (you can also view the original English article)

Final product image
What You'll Be Creating

यह Angular 4 में फॉर्म के परिचय पर सीरीज का दूसरा भाग है। पहले भाग में, हमने टेंप्लेट-ड्रिवन एप्रोच का उपयोग करके एक फॉर्म बनाया। हमने फॉर्म एलिमेंट्स को सुपर चार्ज करने के लिए ngModel, ngModelGroup और ngForm जैसे डायरेक्टिव का उपयोग किया। इस ट्यूटोरियल में, हम फॉर्म्स को बनाने के लिए एक अलग तरीका अपनाएंगे - रिएक्टिव वाला तरीका।

रिएक्टिव फॉर्म्स

टेंप्लेट ड्रिवन फॉर्म्स की तुलना में रिएक्टिव फॉर्म्स एक अलग अप्रोच लेता है। यहां, हम अपने कॉम्पोनेंट क्लास में फॉर्म कण्ट्रोल ऑब्जेक्ट्स को बनाते और इनिशियलाइज़ करते हैं। ये इंटरमीडिएट ऑब्जेक्ट्स है जो फॉर्म के स्टेट को होल्ड करते हैं। हम फिर उन्हें टेंप्लेट में फॉर्म कंट्रोल एलिमेंट्स के साथ बांध देंगे।

फॉर्म कंट्रोल ऑब्जेक्ट इनपुट कंट्रोल वैल्यूज में किसी भी परिवर्तन को सुनता है, और वह तुरंत ऑब्जेक्ट के स्टेट में परिवर्तन कर देता है। क्योंकि कॉम्पोनेंट की डाटा मॉडल स्ट्रक्चर तक सीधी पहुंच होती है, इसलिए सभी परिवर्तन डाटा मॉडल, फॉर्म कंट्रोल ऑब्जेक्ट और इनपुट कंट्रोल वैल्यूज के बीच सिंक्रोनाइज किए जा सकते हैं।

High level overview of Reactive forms using model-driven approach

व्यवहारिक रूप से, अगर हम यूज़र की प्रोफाइल को अपडेट करने के लिए एक फॉर्म का निर्माण करते हैं, तो डाटा मॉडल सर्वर से प्राप्त किया गया यूजर ऑब्जेक्ट होता है। प्रोग्रामिंग की प्रथा के अनुसार, यह अक्सर कॉम्पोनेंट की यूजर प्रॉपर्टी (this.user) के अंदर स्टोर किए जाते हैं। फॉर्म कंट्रोल ऑब्जेक्ट या फॉर्म मॉडल टेंप्लेट के वास्तविक कंट्रोल एलिमेंट्स के साथ बांधा गया होगा।

इन दोनों मॉडलों में समान स्ट्रक्चर होना चाहिए, भले ही वे एक जैसे ना हो। हालांकि, इनपुट वैल्यू सीधे डाटा मॉडल में फ्लो नहीं करनी चाहिए। इमेज यह बताती है कि टेंप्लेट यूजर इनपुट फॉर्म मॉडल के लिए अपना रास्ता कैसे बनाता है।

आएँ शुरू करें।

आवश्यक शर्तें

यदि आप भाग दो को समझना चाहते हैं तो, आपको इस सीरीज के पहले भाग को फॉलो करने की आवश्यकता नहीं है। हालांकि, यदि Angular में फॉर्म्स आपके लिए एक नई बात है, तो मैं टेंप्लेट-ड्रिवन स्ट्रेटेजी के माध्यम से जाने की सलाह दूंगा। इस प्रोजेक्ट के लिए कोड मेरे GitHub रिपोजिटरी पर उपलब्ध है। सुनिश्चित करें कि आप सही ब्रांच पर हैं और फिर ज़िप को डाउनलोड करें या, वैकल्पिक रूप से, फॉर्म को एक्शन में देखने के लिए रेपो को क्लोन करें।

यदि आप इसके बजाय स्क्रैच से शुरू करना पसंद करते हैं, तो सुनिश्चित करें कि आप ने Angular CLI को इंस्टॉल कर लिया हो। नया प्रोजेक्ट बनाने के लिए ng कमांड का उपयोग करें।

इसके बाद, SignupForm के लिए एक नया कॉम्पोनेंट जनरेट करें या मैनुअल रूप से इसे बनाए।

app.component.html के कंटेंट को इसके साथ बदल दे:

यहां src/ डायरेक्टरी के लिए डायरेक्टरी स्ट्रक्चर है। मैंने चीजों को आसान रखने के लिए कुछ गैर जरूरी फाइलों को हटा दिया है।

जैसा कि आप देख सकते हैं, SignupForm कॉम्पोनेन्ट के लिए एक डायरेक्टरी ऑटोमेटिक रूप से बनाई गई है। यहीं पर हमारे अधिकांश कोड दिए जाएंगे। मैंने अपने यूजर मॉडल स्टोर करने के लिए एक नई User.ts को भी बनाया है।

HTML टेम्पलेट

इससे पहले की हम असल में कॉम्पोनेन्ट टेम्पलेट के अंदर काम करना शुरू करें, हमे एक अब्स्ट्रक्ट आईडिया होना चाहिए की हम क्या बना रहे हैं। तो यहाँ वो फॉर्म स्ट्रक्चर है जो मेरे दिमाग में हैं। इस साइनअप फॉर्म में बहुत सारी इनपुट फ़ील्ड्स, एक सेलेक्ट एलिमेंट, और एक चेकबॉक्स एलिमेंट हैं।

The HTML Template

यहाँ वो HTML टेम्पलेट है जिसका हम अपने रजिस्ट्रेशन पेज में प्रयोग करेंगे।

HTML टेम्पलेट

HTML टेंप्लेट के अंदर प्रयोग की जा रही CSS क्लासेज Bootstrap लाइब्रेरी का हिस्सा है जिसका प्रयोग चीजों को सुंदर बनाने के लिए किया जाता है। क्योंकि यह ट्यूटोरियल डिजाइन के लिए नहीं है, मैं जब तक जरूरी ना हो फॉर्म के CSS स्वरूप के बारे में अधिक बात नहीं करूंगा।

बेसिक फॉर्म सेटअप

रिएक्टिव फॉर्म बनाने के लिए, आपको ReactiveFormsModule को @angular/forms से इंपोर्ट करना होगा और इसे app.module.ts में इंपोर्ट ऐरे के अंदर जोड़ना होगा।

app/app.module.ts

इसके बाद, रजिस्ट्रेशन फॉर्म के लिए User मॉडल बनाएं। मॉडल को बनाने के लिए हम एक क्लास या एक इंटरफ़ेस दोनों में से किसी का भी प्रयोग कर सकते हैं। इस ट्यूटोरियल के लिए, मैं नीचे दी गई प्रॉपर्टीज के साथ एक क्लास को एक्सपोर्ट करने जा रहा हूं।

app/User.ts

अब, SignupForm कॉम्पोनेंट के अंदर User मॉडल के एक इंस्टेंस को बनाएं।

app/signup-form/signup-form.component.ts

signup-form.component.html फाइल के लिए, मैं ऊपर बताए गए अनुसार उसी HTML टेंप्लेट का प्रयोग करने जा रहा हूं, पर कुछ छोटे-छोटे परिवर्तनों के साथ। साइनअप फॉर्म में एक सिलेक्ट फील्ड है जिसमें ऑप्शन की एक लिस्ट है। हालांकि यह काम करता है, पर हम इसे Angular के तरीके से करेंगे जिसमें हम ngFor डायरेक्टिव का प्रयोग करके लिस्ट के अंदर लूप करते हैं।

app/signup-form/signup-form.component.html

नोट: आपको शायद एक एरर प्राप्त हो जो कहता हो No provider for ControlContainerएरर तब नजर आता है जब कॉम्पोनेंट के अंदर एक <form> टैग हो वह भी बिना FormGroup डायरेक्टिव के। यह एरर गायब हो जाएगा एक बार जब इस टिटोरियल के आखरी वाले हिस्सों में हम FormGroup डायरेक्टिव को जोड़ते हैं।

हमारे पास हाथ में एक कॉम्पोनेंट, एक मॉडल, और एक फॉर्म टेंप्लेट है। अब क्या? अब अपने हाथ चलाने का और APIs से परिचित होने का समय है जिससे आप रिएक्टिव फॉर्म्स को बना सकें। इसमें FormControl और FormGroup शामिल है।

FormControl का उपयोग करके स्टेट को ट्रैक करना

जब हम रिएक्टिव फॉर्म्स की स्ट्रेटेजी के अनुसार फॉर्म बनाते हैं, तो आपका सामना ngModel और ngForm डायरेक्टिव के साथ नहीं होता। इसके बजाय, हम अंतर्निहित FormControl और FormGroup API का उपयोग करते हैं।

FormControl एक डायरेक्टिव है जिसका उपयोग FormControl के इंस्टेंस को बनाने के लिए किया जाता है जिससे आप किसी विशेष फॉर्म एलिमेंट के स्टेट और उसके वैलिडेशन स्टेटस को ट्रैक कर सकते हैं। यहां आप देख सकते हैं कि FormControl कैसे काम करता है:

email अब एक FormControl का इंस्टेंस है, और आप इसे अपने टेंप्लेट में इनपुट कंट्रोल एलिमेंट के रूप में बांध सकते हैं:

टेंप्लेट फॉर्म एलिमेंट अब कंपोनेंट में FormControl इंस्टेंस के साथ बंधा हुआ है। इसका मतलब यह है कि इनपुट कंट्रोल वैल्यू में कोई भी परिवर्तन दूसरे छोर पर रिफ्लेक्ट होता है।

एक FormControl कंस्ट्रक्टर तीन अरगुमेंट्स को स्वीकार करता है - एक शुरुआती वैल्यू, sync वैलिडेटर का एक ऐरे, और async वैलिडेटर का एक ऐरे—और जैसा कि आपने अंदाजा लगा लिया होगा, यह सभी ऑप्शनल है। हम यहां पहले दो अरगुमेंट्स को कवर करेंगे।

Angular में बिल्ट-इन वैलिडेटर्स का एक सीमित सेट है। लोकप्रिय वैलिडेटर मेथड्स में Validators.required, Validators.minLength, Validators.maxlength, और Validators.pattern शामिल है। हालांकि, उनका उपयोग करने के लिए, आपको पहले Validator API को इंपोर्ट करना होगा।

हमारे साइनअप फॉर्म के लिए, हमारे पास कई इनपुट कंट्रोल फील्ड (email और password के लिए), एक सिलेक्टर फील्ड और एक चेक बॉक्स फील्ड है। अलग अलग FormControl ऑब्जेक्ट बनाने के बजाय, क्या इन सभी FormControl को एक एनटीटी के तहत ग्रुप बनाना अधिक उपयोगी नहीं होगा? यह फायदेमंद है क्योंकि अब हम एक ही स्थान पर सभी sub-FormControl ऑब्जेक्ट्स की वैल्यू और वैलिडिटी को ट्रैक कर सकते हैं। FormGroup इसी काम के लिए होता है। तो हम एक पेरेंट FormGroup को कई चाइल्ड FormControls के साथ रजिस्टर करेंगे।

कई सारे FormControls को FormGroup के साथ ग्रुप करना

FormGroup को जोड़ने के लिए, सबसे पहले इसे इंपोर्ट करें। इसके बाद, signupForm को एक क्लास प्रॉपर्टी के रूप में डिक्लेअर करें और इसे कुछ इस प्रकार इनिशियलाइज़ करें:

app/signup-form/signup-form.component.ts

FormGroup मॉडल को DOM के साथ कुछ इस प्रकार बाइंड करें:

app/signup-form/signup-form.component.ts

[formGroup] = "signupForm" Angular को बताता है के आप इस फॉर्म को कॉम्पोनेंट क्लास में डिक्लेअर किए गए FormGroup के साथ जोड़ना चाहते हैं। जब Angular formControlName=”email” को देखता है, तो यह पैरंट FormGroup के अंदर key वैल्यू email के साथ FormControl के इंस्टेंस को चेक करता है।

इसी तरह से, अन्य फॉर्मल एलिमेंट्स को FormControlName=”value” एट्रिब्यूट डालकर अपडेट करें जैसा कि हमने अभी किया।

यह देखने के लिए कि क्या सब कुछ उम्मीद के मुताबिक काम कर रहा है, और फार्म टैग के बाद निम्नलिखित को जोड़ें:

app/signup-form/signup-form.component.html

ब्राउज़र में JSON के रूप में मॉडल को रेंडर करने के लिए JsonPipe के माध्यम से SignupForm प्रॉपर्टी को पाइप करें। यह डीबगिंग और लॉगिंग के लिए सहायक होती है। आपको कुछ इस तरह से JSON आउटपुट दिखना चाहिए।

Form state and validty in Model-driven forms

यहां दो बातें ध्यान देने योग्य है:

  1. JSON और यूजर मॉडल के स्ट्रक्चर आपस में बिल्कुल मेल नहीं खाते है जिसे हमने पहले बनाया था।
  2. signupForm.status दिखाता है कि फॉर्म का स्टेटस INVALID है। यह स्पष्ट रूप से दिखाता है कि ई-मेल कंट्रोल फील्ड पर Validators.required वैसा ही काम कर रहा है जैसा हम चाहते हैं।

फॉर्म मॉडल और डाटा मॉडल के स्ट्रक्चर को आपस में मैच होना चाहिए।

डाटा मॉडल के पदानुक्रमित स्ट्रक्चर प्राप्त करने के लिए, हमें एक नेस्टेड FormGroup का उपयोग करना चाहिए। इसके अतिरिक्त, सिंगल FormGroup के अंडर में संबंधित फॉर्म एलिमेंट रखना हमेशा एक अच्छा विचार होता है।

नेस्टेड FormGroup

पासवर्ड के लिए एक नया FormGroup बनाएं।

app/signup-form/signup-form.component.ts

अब, DOM के साथ नए फॉर्म मॉडल को बांधने के लिए, निम्नलिखित बदलाव करें:

app/signup-form/signup-form.component.html

formGroupName = “password” नेस्टेड FormGroup के लिए बाइंडिंग करता है। अब, फॉर्म मॉडल का स्ट्रक्चर हमारी आवश्यकताओं से मेल खाता है।

इसके बाद, हमें फॉर्म कंट्रोल्स को वैलिडेट करने की आवश्यकता है।

फॉर्म को वैलिडेट करना

ई-मेल इनपुट कंट्रोल के लिए हमारे पास एक साधारण वैलिडेशन है। हालांकि, यह पर्याप्त नहीं है। वैलिडेशन के लिए हमारी रिक्वायरमेंट्स की पूरी लिस्ट यहां दी गई है।

  • सभी फॉर्म कंट्रोल एलिमेंट्स required है।
  • फॉर्म के स्टेटस को VALID होने तक सबमिट बटन को डिसएबल करें।
  • ई-मेल फील्ड में स्ट्रिक्टली ईमेल आईडी ही होनी चाहिए।
  • पासवर्ड फील्ड कि न्यूनतम लंबाई 8 होनी चाहिए।
Validating the form

पहला वाला आसान है। फॉर्म मॉडल में सभी FormControls के लिए Validator.required को जोड़ें।

app/signup-form/signup-form.component.ts

इसके बाद, जब तक फॉर्म INVALID हो बटन को डिसएबल करें।

app/signup-form/signup-form.component.html

ई-मेल पर एक कंस्ट्रेंट जोड़ने के लिए, आप या तो डिफॉल्ट Validators.email का उपयोग कर सकते हैं या एक कस्टम Validators.pattern() बना सकते हैं जो नीचे बताए गए जैसे रेगुलर एक्सप्रेशन को निर्दिष्ट करता है।

पासवर्ड फील्ड के लिए minLength वेलीडेटर का उपयोग करें।

वैलिडेशन के लिए बस इतना ही। हालांकि, फॉर्म मॉडल लॉजिक अव्यवस्थित और दोहराव वाला दिखाई दे रहा है। पहले उसे साफ करते हैं।

FormBuilder का उपयोग करके कोड को रीफेक्टर करना

Angular आपको FormGroup और FormControl के नए इंस्टेंसस बनाने के लिए एक सिंटेक्स शुगर प्रदान करता है जिसे FormBuilder कहा जाता है। FormBuilder API यहां हमारे द्वारा कवर की गई चीजों के अलावा कुछ विशेष नहीं करती है।

यह हमारे कोड को सिम्पलीफाई बनाती है और देखने में फॉर्म बनाने की प्रक्रिया को आसान बनाती है। FormBuilder बनाने के लिए, आपको इसे signup-form.component.ts में इंपोर्ट करना होगा और FormBuilder को कंस्ट्रक्टर में इंजेक्ट करना होगा।

app/signup-form/signup-form.component.ts

एक नया FormGroup() बनाने के बजाय, हम एक फॉर्म बनाने के लिए this.fb.group का उपयोग कर रहे हैं। सिंटेक्स को छोड़कर, बाकी सब कुछ वैसा ही बना रहता है।

app/signup-form/signup-form.component.ts

वैलिडेशन एरर्स को दिखाना

एरर्स को दिखाने के लिए, मैं एक कंडीशनर डायरेक्टिव ngIf का प्रयोग div एलिमेंट पर करने जा रहा हूं। आइए ई-मेल के लिए इनपुट कंट्रोल फील्ड से शुरू करते हैं:

यहां कुछ मुद्दे हैं।

  1. invalid और pristine कहां से आ गए?
  2. signupForm.controls.email.invalid बहुत लंबा और गहरा है।
  3. एरर स्पष्ट रूप से यह नहीं बताता की यह इनवेलिड क्यों है।

पहले प्रश्न का उत्तर देने के लिए, प्रत्येक FormControl में कुछ प्रॉपर्टी होती है जैसे कि invalid, valid, pristine, dirty, touched, और untouched। हम यह निर्धारित करने के लिए उपयोग कर सकते हैं कि एरर मैसेज या वार्निंग प्रदर्शित किए जाने चाहिए या नहीं। नीचे दी गई इमेज उन सभी प्रॉपर्टीज का विस्तार से वर्णन करती है।

 FormControl Properties in Angular Reactive approach

तो *ngIf के साथ div एलिमेंट को केवल तभी प्रदर्शित किया जाएगा जब ईमेल इनवेलिड हो। हालांकि, यूजर का फील्ड एडिट करने से पहले ही ब्लेंक होने वाली इनपुट फील्ड्स के बारे में एरर्स के साथ स्वागत किया जाएगा।

इस सिनेरियो से बचने के लिए, हमने दूसरी कंडीशन जोड़ी है। कंट्रोल पर विजिट किए जाने के बाद ही एरर को प्रदर्शित किया जाएगा।

मेथड्स के नामों की लंबी श्रृंखला (signupForm.controls.email.invalid) से छुटकारा पाने के लिए, मैं कुछ शॉर्टहैंड गेटर मेथड्स जोड़ने जा रहा हूं। यह उन्हें अधिक सुलभ और संक्षिप्त रखता है।

app/signup-form/signup-form.component.ts

एरर को और अधिक स्पष्ट करने के लिए, मैंने नेस्टेड ngIf कंडीशन को नीचे जोड़ा है:

app/signup-form/signup-form.component.html

हम सभी संभावित वैलिडेशन एरर्स को चेक करने के लिए email.errors का उपयोग करते हैं और फिर उन्हें कस्टम मैसेजेस के रूप में यूजर को वापस प्रदर्शित करते हैं। अब, अन्य फॉर्म एलिमेंट्स के लिए इसी प्रकार की प्रक्रिया का पालन करें। यहां बताया गया है कि मैंने पासवर्ड और टर्म्स इनपुट कंट्रोल के लिए वैलिडेशन को कैसे कोड किया है।

app/signup-form/signup-form.component.html

ngSubmit का उपयोग करके फॉर्म को सबमिट करें

हमने लगभग फॉर्म को पूरा कर लिया है। इसमें सबमिट फंक्शनैलिटी की कमी है, जिसे हम अब लागू करने वाले हैं।

फॉर्म को सबमिट करने पर, फॉर्म मॉडल वैल्यू कॉम्पोनेंट प्रॉपर्टी में प्रवाहित होनी चाहिए।

app/signup-form/signup-form.component.ts

अंतिम डेमो

यहाँ एप्लीकेशन का अंतिम वर्जन है। मैंने कुछ बूटस्ट्रैप की क्लासेज को भी जोड़ दिया है ताकि फॉर्म प्यारा दिखे।

सब कुछ समाप्त करते हैं

यदि आप शुरू से ही इस ट्यूटोरियल सीरीज को फॉलो कर रही हैं, तो हमारे पास Angular में दो लोकप्रिय फॉर्म बिल्डिंग टेक्नोलॉजी का अच्छा अनुभव है। टेंप्लेट-ड्रिवन और मॉडल-ड्रिवन तकनीक एक ही चीज को प्राप्त करने के दो तरीके हैं। व्यक्तिगत रूप से, मैं नीचे दिए गए कारणों की वजह से रिएक्टिव फॉर्म्स का उपयोग करना ज्यादा पसंद करता हूं:

  • सभी फॉर्म वैलिडेशन लॉजिक एक ही स्थान पर स्थित होते हैं - आपकी कॉम्पोनेंट क्लास के अंदर। यह टेंप्लेट एप्रोच की तुलना में अधिक उत्पादक है, जहां ngModel डायरेक्टिव पूरे टेंप्लेट में बिखरे हुए हैं।
  • टेंप्लेट-ड्रिवन फॉर्म्स के विपरीत, मॉडल-ड्रिवन फॉर्म्स को टेस्ट करना आसान है। आपको अपने फॉर्म को टेस्ट करने के लिए एंड-टू-एंड टेस्टिंग लाइब्रेरी का सहारा नहीं लेना होता।
  • वैलिडेशन लॉजिक कॉम्पोनेंट क्लास के अंदर जाएगा और टेंप्लेट में नहीं।
  • बड़ी संख्या में फॉर्म एलिमेंट्स के साथ एक फॉर्म के लिए, इस एप्रोच में FormBuilder नाम का कुछ मौजूद है, जिसमें FormControl ऑब्जेक्ट्स का निर्माण करना आसान हो जाता है।

हम यहां एक चीज छूट गयी हैं, और वह पासवर्ड मिसमैच के लिए एक वैलिडेशन लिखना है। सीरीज के अंतिम भाग में, हम आपको Angular में कस्टम वैलिडेशन फंक्शन को बनाने के बारे में जानने के लिए आवश्यक सभी चीजों को कवर करेंगे। तब तक के लिए बने रहिए।

इस बीच आपको पढ़ने, अध्ययन करने और उपयोग करने के लिए Envato Market में बहुत सी वस्तुओं के साथ, आप को व्यस्त रखने के लिए बहुत सारे फ्रेमवर्क्स और लाइब्रेरीज है।

Advertisement
Advertisement
Looking for something to help kick start your next project?
Envato Market has a range of items for sale to help get you started.