2016-06-24 16 views
35

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

मैं

क्या कोशिश की है मैं क्षेत्रों का एक सेट बनाया है (3 सलेक्ट बॉक्स पूरा करने के लिए मदद और 1 टेक्स्ट बॉक्स), मैंने ऐड फ़ील्ड्स नामक एक बटन बनाया है, लेकिन मैंने इसे कोणीय 1.x में करने की कोशिश की है, लेकिन यह कोणीय 2 में है, मुझे नहीं पता कि इसे कैसे पूरा किया जाए, यह मेरा पूरा काम link है

app/app.component.ts 
import { 
    Component 
    } 
from '@angular/core'; 
    @Component({ 
    selector: 'my-app', 
    template: ` 
    <h1>{{title}}</h1> 
    <div class="container"> 
    <button class="btn btn-success bt-sm">add</button> 
    <form role="form" calss="form-inline"> 
    <div class="form-group col-xs-3"> 
    <label>Select State:</label> 
    <select class="form-control" [(ngModel)]="rules.State" id="sel1"> 
      <option>State1</option> 
      <option>State2</option> 
      <option>State3</option> 
      <option>State4</option> 
</select> 
    </div> 
    <div class="form-group col-xs-3"> 
<label>Rule:</label> 
    <input type="text" data-toggle="modal" data-target="#myModal" class="form-     control"> 
    </div> 
<div class="form-group col-xs-3"> 
<label>Pass State :</label> 
    <select class="form-control" [(ngModel)]="rules.pass"> 
    <option>State1</option> 
    <option>State2</option> 
    <option>State3</option> 
    <option>State4</option> 
</select> 
</div> 
<div class="form-group col-xs-3"> 
    <label>Fail State:</label> 
     <select class="form-control" [(ngModel)]="rules.fail"> 
     <option>State1</option> 
     <option>State2</option> 
     <option>State3</option> 
    <option>State4</option> 
    </select> 
     </div> 
    </form> 
    </div> 
<div class="modal fade" id="myModal" role="dialog"> 
     <div class="modal-dialog"> 
      <div class="modal-content"> 
       <div class="modal-header"> 
        <button type="button" class="close" data-dismiss="modal">&times </button> 
        <h4 class="modal-title">Rules Configuration</h4> 
       </div> 
       <div class="modal-body"> 
       <p>Rules</p> 
       </div> 
       <div class="modal-footer"> 
       <button type="button" class="btn btn-default" data- dismiss="modal">Close</button> 
       </div> 
      </div> 

       </div> 
       </div> 
` 
    }) 
    export class AppComponent { 
      title = 'Rule Engine Demo'; 
      rules: Rules = { 
        State: '', 
        pass: '', 
       fail: '' 
       }; 
+1

आप इस http://stackoverflow.com/questions/36627573/angular2-form-controlgroup-who-hold-an-undefined-number-of-control/36641967#36641967 –

+0

@A_Singh को प्राप्त करने के लिए 'नियंत्रण समूह' का उपयोग कर सकते हैं क्या आपको कोई विचार है कि क्यों कोणीय 2 टेम्पलेट एचटीएमएल आंतरिक स्क्रिप्ट कोड लोड नहीं कर रहा है –

+0

क्या आपका मतलब है '[आंतरिक HTML]' का उपयोग करके स्क्रिप्ट इंजेक्शन करना काम नहीं करता है? ऐसा इसलिए है क्योंकि कोणीय स्क्रिप्ट को इंजेक्शन देने की इजाजत नहीं देता है –

उत्तर

109

यह कुछ महीने देर हो चुकी है, लेकिन मैंने सोचा कि मैं this here tutorial पर आधारित अपना समाधान प्रदान करूंगा। इसका अर्थ यह है कि जब आप फ़ॉर्म के दृष्टिकोण के तरीके को बदलते हैं तो इसे प्रबंधित करना बहुत आसान होता है।

सबसे पहले, सामान्य FormsModule के बजाय या ReactiveFormsModule का उपयोग करें। प्रतिक्रियाशील रूपों के साथ आप अपने घटकों/सेवाओं में अपने फॉर्म बनाते हैं और फिर फॉर्म को स्वयं उत्पन्न करने वाले पृष्ठ के बजाय उन्हें अपने पृष्ठ में प्लग करते हैं। यह थोड़ा और कोड है लेकिन यह बहुत अधिक परीक्षण योग्य है, बहुत अधिक लचीला है, और जहां तक ​​मैं बहुत सारे गैर-तुच्छ रूपों को बनाने का सबसे अच्छा तरीका बता सकता हूं।

अंतिम परिणाम एक छोटे से इस तरह दिखेगा, धारणात्मक:

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

  • उस FormGroup उदाहरण के अंदर एक या अधिक FormArray उदाहरण होंगे। FormArray मूल रूप से एकाधिक नियंत्रणों को एक साथ समूहित करने और उन पर पुनरावृत्ति करने का एक तरीका है। आप अपने सरणी में कई FormGroup उदाहरण भी डाल सकते हैं और उनको अपने बड़े रूप में निहित "मिनी-फॉर्म" के रूप में उपयोग कर सकते हैं।

  • एक गतिशील FormArray के भीतर कई FormGroup और/या FormControl उदाहरणों नेस्टिंग रखकर आप वैधता को नियंत्रित करने और एक, बड़ा, प्रतिक्रियाशील कई गतिशील के योग से बना टुकड़े के रूप में प्रपत्र प्रबंधन कर सकते हैं। उदाहरण के लिए, यदि आप यह जांचना चाहते हैं कि उपयोगकर्ता को सबमिट करने से पहले प्रत्येक इनपुट मान्य है, तो एक उप-फॉर्म की वैधता शीर्ष-स्तर के रूप में "बबल अप" होगी और पूरा फॉर्म अमान्य हो जाएगा, जिससे इसे आसान बना दिया जा सके गतिशील इनपुट का प्रबंधन करें।

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

मामले में ट्यूटोरियल मैं से जुड़ा हुआ नीचे चला जाता है, यहाँ कुछ नमूना कोड आप अपने आप को लागू कर सकते हैं (मेरे उदाहरण टाइपप्रति का उपयोग करें) है कि बुनियादी विचारों को दर्शाते हैं:

बेस घटक कोड:

import { Component, Input, OnInit } from '@angular/core'; 
import { FormArray, FormBuilder, FormGroup, Validators } from '@angular/forms'; 

@Component({ 
    selector: 'my-form-component', 
    templateUrl: './my-form.component.html' 
}) 
export class MyFormComponent implements OnInit { 
    @Input() inputArray: ArrayType[]; 
    myForm: FormGroup; 

    constructor(private fb: FormBuilder) {} 
    ngOnInit(): void { 
     let newForm = this.fb.group({ 
      appearsOnce: ['InitialValue', [Validators.required, Validators.maxLength(25)]], 
      formArray: this.fb.array([]) 
     }); 

     const arrayControl = <FormArray>newForm.controls['formArray']; 
     this.inputArray.forEach(item => { 
      let newGroup = this.fb.group({ 
       itemPropertyOne: ['InitialValue', [Validators.required]], 
       itemPropertyTwo: ['InitialValue', [Validators.minLength(5), Validators.maxLength(20)]] 
      }); 
      arrayControl.push(newGroup); 
     }); 

     this.myForm = newForm; 
    } 
    addInput(): void { 
     const arrayControl = <FormArray>this.myForm.controls['formArray']; 
     let newGroup = this.fb.group({ 

      /* Fill this in identically to the one in ngOnInit */ 

     }); 
     arrayControl.push(newGroup); 
    } 
    delInput(index: number): void { 
     const arrayControl = <FormArray>this.myForm.controls['formArray']; 
     arrayControl.removeAt(index); 
    } 
    onSubmit(): void { 
     console.log(this.myForm.value); 
     // Your form value is outputted as a JavaScript object. 
     // Parse it as JSON or take the values necessary to use as you like 
    } 
} 

उप-घटक कोड: (प्रत्येक नए इनपुट क्षेत्र के लिए एक, चीजों को साफ रखने के)

import { Component, Input } from '@angular/core'; 
import { FormGroup } from '@angular/forms'; 

@Component({ 
    selector: 'my-form-sub-component', 
    templateUrl: './my-form-sub-component.html' 
}) 
export class MyFormSubComponent { 
    @Input() myForm: FormGroup; // This component is passed a FormGroup from the base component template 
} 

बेस घटक एचटीएमएल

<form [formGroup]="myForm" (ngSubmit)="onSubmit()" novalidate> 
    <label>Appears Once:</label> 
    <input type="text" formControlName="appearsOnce" /> 

    <div formArrayName="formArray"> 
     <div *ngFor="let control of myForm.controls['formArray'].controls; let i = index"> 
      <button type="button" (click)="delInput(i)">Delete</button> 
      <my-form-sub-component [myForm]="myForm.controls.formArray.controls[i]"></my-form-sub-component> 
     </div> 
    </div> 
    <button type="button" (click)="addInput()">Add</button> 
    <button type="submit" [disabled]="!myForm.valid">Save</button> 
</form> 

उप-घटक एचटीएमएल

<div [formGroup]="form"> 
    <label>Property One: </label> 
    <input type="text" formControlName="propertyOne"/> 

    <label >Property Two: </label> 
    <input type="number" formControlName="propertyTwo"/> 
</div> 

उपरोक्त कोड में मैं मूल रूप से एक घटक है कि प्रपत्र के आधार का प्रतिनिधित्व करता है और उसके बाद प्रत्येक उप है -कंपोनेंट के अंदर स्थित FormArray के भीतर अपना FormGroup उदाहरण प्रबंधित करता है। आधार टेम्पलेट उप-समूह के साथ उप-घटक में गुजरता है और फिर आप पूरे रूप में गतिशील रूप से सत्यापन को संभाल सकते हैं।

इसके अलावा, यह फ़ॉर्म से रणनीतिक रूप से डालने और उन्हें हटाने के द्वारा घटक को पुन: क्रमबद्ध करने के लिए तुच्छ बनाता है। यह किसी भी संख्या में इनपुट (प्रतीत होता है) के साथ काम करता है क्योंकि वे नामों के साथ संघर्ष नहीं करते हैं (जहां तक ​​मुझे पता है टेम्पलेट संचालित रूपों का एक बड़ा नकारात्मक पक्ष) और आप अभी भी बहुत अधिक स्वचालित सत्यापन बनाए रखते हैं। इस दृष्टिकोण का एकमात्र "नकारात्मक" है, थोड़ा और कोड लिखने के अलावा, आपको यह निर्धारित करना होगा कि फॉर्म कैसे काम करते हैं। हालांकि, जब आप आगे बढ़ते हैं तो यह अधिक बड़े और अधिक गतिशील रूपों के लिए संभावनाएं खुलता है।

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

+1

है कि उस फ़ॉर्म में ngModel कैसे कार्यान्वित करें? – elporfirio

+0

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

+0

हां ऊपर से ऊपर यह मेरे लिए काम करता है, लेकिन मुझे उपरोक्त चीज़ पर कस्टम निर्देश कैसे लागू नहीं किया जा रहा है – Runali