कोणीय अभिक्रियाशील: चेकबॉक्स मानों की एक सरणी का निर्माण?


104

उसी से संबंधित चेकबॉक्स की सूची को देखते हुए formControlName, मैं कैसे / के formControlबजाय चेकबॉक्स मानों की एक सरणी का निर्माण कर सकता हूं ?truefalse

उदाहरण:

<form [formGroup]="checkboxGroup">
    <input type="checkbox" id="checkbox-1" value="value-1" formControlName="myValues" />
    <input type="checkbox" id="checkbox-2" value="value-2" formControlName="myValues" />
    <input type="checkbox" id="checkbox-3" value="value-2" formControlName="myValues" />
</form>

checkboxGroup.controls['myValues'].value वर्तमान में उत्पादन:

true or false

मैं इसका उत्पादन करना चाहता हूं:

['value-1', 'value-2', ...]

क्या आपको कोई हल मिला?
CP

यह शायद एक फॉर्म में चेकबॉक्स करने के लिए सबसे अधिक इंजीनियर तरीका है। यह बिल्कुल सीधा नहीं है।
मेवल्सन

8
कोणीय। मैं जो कुछ करने की कोशिश कर रहा हूं वह मेरे प्रतिक्रियात्मक रूप में बांधने के लिए एक मैट-रेडियो-समूह प्राप्त करने के लिए है। मुझे कोणीय के साथ इतना संघर्ष करना याद नहीं है। सभी लेख एक ही बात की ओर इशारा कर रहे हैं। बस यह काम करने के लिए नहीं मिल सकता है। बाकी सब कुछ सीधा है। मैं शायद इसे बहुत लंबे समय से देख रहा हूं। अभी भी बस एक तरह से एक सरणी मूल्य के लिए बहुत अधिक जटिलता की तरह लगता है।
मेवल्सन

3
हाँ, यह भयानक था जब मैंने 2016 में यह पूछा, और यह 2019 में अभी भी भयानक है।
ReactingToAngularVues

3
मैं इस प्रश्न में एक टन नहीं जोड़ रहा हूं, लेकिन मैं चाहता था कि यह दूसरों को पता हो कि मैं उसी तरह महसूस करता हूं। यह अकेले कोणीय प्रतिक्रियाशील रूपों को सीखने में सबसे कठिन हिस्सा रहा है। मुझे ऐसा लगता है कि यह बिल्कुल मुश्किल नहीं होना चाहिए। मैं यह देखकर खुश हूँ कि मैं संघर्ष में अकेला नहीं हूँ, हालाँकि। तो सवाल पोस्ट करने के लिए धन्यवाद।
नॉर्थस्टारकोड

जवाबों:


52

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

मैं प्रपत्र में मानों को जोड़ने या निकालने के लिए एक विधि का उपयोग करता हूं। यह एक बुरा दृष्टिकोण हो सकता है, लेकिन यह काम करता है!

component.html

<div *ngFor="let choice of checks; let i=index" class="col-md-2">
  <label>
    <input type="checkbox" [value]="choice.value" (change)="onCheckChange($event)">
    {{choice.description}}
  </label>
</div>

component.ts

// For example, an array of choices
public checks: Array<ChoiceClass> = [
  {description: 'descr1', value: 'value1'},
  {description: "descr2", value: 'value2'},
  {description: "descr3", value: 'value3'}
];

initModelForm(): FormGroup{
  return this._fb.group({
    otherControls: [''],
    // The formArray, empty 
    myChoices: new FormArray([]),
  }
}

onCheckChange(event) {
  const formArray: FormArray = this.myForm.get('myChoices') as FormArray;

  /* Selected */
  if(event.target.checked){
    // Add a new control in the arrayForm
    formArray.push(new FormControl(event.target.value));
  }
  /* unselected */
  else{
    // find the unselected element
    let i: number = 0;

    formArray.controls.forEach((ctrl: FormControl) => {
      if(ctrl.value == event.target.value) {
        // Remove the unselected element from the arrayForm
        formArray.removeAt(i);
        return;
      }

      i++;
    });
  }
}

जब मैं अपना फॉर्म जमा करता हूं, उदाहरण के लिए मेरा मॉडल दिखता है:

  otherControls : "foo",
  myChoices : ['value1', 'value2']

केवल एक चीज गायब है, फॉर्म भरने के लिए एक फ़ंक्शन यदि आपके मॉडल में पहले से ही चेक किए गए मान हैं।


यदि मैं आपके उदाहरण को db में दर्ज करने के बाद डेटा लोड करता हूं, तो मैं कैसे चेकअप कर सकता हूं?
देवरा

इस समाधान में हमेशा फॉर्म को मान्य किया जा रहा है भले ही चेकबॉक्स चयनित न हो
तेजा

myChoices: new FormArray([], Validators.required)
बिक्रम नाथ

48

यहां https://angular.io/docs/ts/latest/api/forms/index/FormArray-class.html का उपयोग करने के लिए एक अच्छी जगह हैFormArray

एक साथ या तो शुरू हम नियंत्रण के बारे में हमारी सरणी का निर्माण करेंगे करने के लिए FormBuilderया एक अप NewingFormArray

FormBuilder

this.checkboxGroup = _fb.group({
  myValues: _fb.array([true, false, true])
});

नया फॉर्मअरे

let checkboxArray = new FormArray([
  new FormControl(true),
  new FormControl(false),
  new FormControl(true)]);

this.checkboxGroup = _fb.group({
  myValues: checkboxArray
});

करने के लिए काफी आसान है, लेकिन फिर हम अपने टेम्पलेट को बदलने जा रहे हैं और टेम्प्लेटिंग इंजन को संभालते हैं कि हम अपने नियंत्रणों से कैसे बंधते हैं:

template.html

<form [formGroup]="checkboxGroup">
    <input *ngFor="let control of checkboxGroup.controls['myValues'].controls"
    type="checkbox" id="checkbox-1" value="value-1" [formControl]="control" />     
  </form>

यहां हम अपने सेट FormControlsमें अपने myValues FormArrayप्रत्येक पर और प्रत्येक नियंत्रण के लिए हम [formControl]नियंत्रण के बजाय उस नियंत्रण के लिए बाध्य कर रहे हैं FormArrayऔर अपने टेम्पलेट सिंटैक्स को थोड़ा कम मैनुअल बनाते हुए भी <div>{{checkboxGroup.controls['myValues'].value}}</div>उत्पादन true,false,trueकर रहे हैं।

आप इस उदाहरण का उपयोग कर सकते हैं: http://plnkr.co/edit/a9OdMAq2YIwQFo7gixbj?p= इधर-उधर झांकना


1
शायद आपको आईडी = "xxx" को हटा देना चाहिए, आईडी को सही होना चाहिए?
पेईसॉन्ग जिओंग

1
आईडी के लिए इस्तेमाल किया जा सकता है सूचकांक *ngFor="let control of checkboxGroup.controls['myValues'].controls ; let i=index""
मिर्जा

9
यह अच्छा है, लेकिन पूरी तरह से सामान्य चेकबॉक्स का सरणी पैदा करता है। संभवतः आप एक सरणी या कुछ और में लोड कर रहे हैं, और प्रत्येक चेकबॉक्स को कुछ अन्य मूल्य के साथ जोड़ देंगे। उदाहरण के लिए, प्रत्येक प्रपत्र नियंत्रण के लिए प्रपत्र लेबल में उपयोग के लिए पाठ स्ट्रिंग कैसे जोड़ते हैं?
Askdesigners

NM मैंने अभी इसे बाहरी सरणी के बगल में मैप किया है: p
Askdesigners

@Askdesigners क्या आप चेकबॉक्स और लेबल के लिए अपना समाधान पोस्ट कर सकते हैं?
eddygeek

25

यह पिछले 6 संस्करणों की तुलना में एंगुलर 6 में ऐसा करना काफी आसान है, यहां तक ​​कि जब चेकबॉक्स की जानकारी एक एपीआई से अतुल्यकालिक रूप से आबादी होती है।

एहसास करने वाली पहली बात यह है कि एंगुलर 6 के keyvalueपाइप के लिए धन्यवाद हमें FormArrayअब और उपयोग करने की आवश्यकता नहीं है, और इसके बजाय घोंसला बना सकता है FormGroup

सबसे पहले, FormBuilder को कंस्ट्रक्टर में पास करें

constructor(
    private _formBuilder: FormBuilder,
) { }

फिर हमारे फॉर्म को इनिशियलाइज़ करें।

ngOnInit() {

    this.form = this._formBuilder.group({
        'checkboxes': this._formBuilder.group({}),
    });

}

जब हमारा चेकबॉक्स विकल्प डेटा उपलब्ध है, तो इसे पुनरावृत्त करें और हम इसे सीधे FormGroupनामांकित के रूप में नेस्टेड में डाल सकते हैं FormControl, बिना संख्या अनुक्रमित लुकअप सरणियों पर भरोसा करने के लिए।

const checkboxes = <FormGroup>this.form.get('checkboxes');
options.forEach((option: any) => {
    checkboxes.addControl(option.title, new FormControl(true));
});

अंत में, टेम्पलेट में हमें बस keyvalueचेकबॉक्स को पुनरावृत्त करना होगा : कोई अतिरिक्त नहीं let index = i, और चेकबॉक्स स्वचालित रूप से वर्णानुक्रम में होगा: बहुत क्लीनर।

<form [formGroup]="form">

    <h3>Options</h3>

    <div formGroupName="checkboxes">

        <ul>
            <li *ngFor="let item of form.get('checkboxes').value | keyvalue">
                <label>
                    <input type="checkbox" [formControlName]="item.key" [value]="item.value" /> {{ item.key }}
                </label>
            </li>
        </ul>

    </div>

</form>

1
चेकबॉक्स मूल्यों की एक साधारण हार्डकोड सरणी के मामले में बहुत उपयोगी है। फिर आप ngOnInit () में तुरंत लूप के लिए एक समान नियंत्रण का उपयोग करके प्रपत्र नियंत्रण जोड़ सकते हैं, और आपके फ़ॉर्म के चेकबॉक्स गतिशील रूप से चेकबॉक्स मान सरणी
Arjan

3
यह अभी भी अंश [key1 = true, key2 = false, key3 = true]। हम चाहते हैं ['की 1', 'की 3']
f.khantsis

@ f.khantsis आप इसे इस तरह से कर सकते हैं: `कास्ट वैल्यू = {key1: true, key2: false, key3, true}; const list = Object.entries (मान) ।filter (([_, iselected]) => isSelected) .map (([key]) => key); console.log (सूची); `
ज़ौनी

1
सबसे अच्छा समाधान imho। आप फॉर्च्यूनर के const checkboxes = ..बाहर असाइनमेंट रख सकते हैं ;)
बर्नौली आईटी

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

9

यदि आप JSON फॉर्मेट में चेकबॉक्स मानों की तलाश कर रहे हैं

{ "name": "", "countries": [ { "US": true }, { "Germany": true }, { "France": true } ] }

पूरा उदाहरण यहां

मैं प्रश्न में उन लोगों के बजाय देश के नाम को चेकबॉक्स मान के रूप में उपयोग करने के लिए माफी माँगता हूँ। आगे की खोज -

फॉर्म के लिए एक फॉर्मग्रुप बनाएं

 createForm() {

    //Form Group for a Hero Form
    this.heroForm = this.fb.group({
      name: '',
      countries: this.fb.array([])
    });

    let countries=['US','Germany','France'];

    this.setCountries(countries);}
 }

प्रत्येक चेकबॉक्स को एक ऑब्जेक्ट से निर्मित एक FormGroup होने दें, जिसकी एकमात्र संपत्ति चेकबॉक्स का मूल्य है।

 setCountries(countries:string[]) {

    //One Form Group for one country
    const countriesFGs = countries.map(country =>{
            let obj={};obj[country]=true;
            return this.fb.group(obj)
    });

    const countryFormArray = this.fb.array(countriesFGs);
    this.heroForm.setControl('countries', countryFormArray);
  }

चेकबॉक्स के लिए फॉर्मग्रुप्स की सरणी का उपयोग मूल प्रपत्र में 'देशों' के लिए नियंत्रण सेट करने के लिए किया जाता है।

  get countries(): FormArray {
      return this.heroForm.get('countries') as FormArray;
  };

टेम्पलेट में, चेकबॉक्स नियंत्रण के लिए नाम प्राप्त करने के लिए एक पाइप का उपयोग करें

  <div formArrayName="countries" class="well well-lg">
      <div *ngFor="let country of countries.controls; let i=index" [formGroupName]="i" >
          <div *ngFor="let key of country.controls | mapToKeys" >
              <input type="checkbox" formControlName="{{key.key}}">{{key.key}}
          </div>
      </div>
  </div>

6

टी एल; डॉ

  1. मैं चेकबॉक्स की सूची को पॉप्युलेट करने के लिए फॉर्मग्रुप का उपयोग करना पसंद करता हूं
  2. कम से कम एक चेकबॉक्स का चयन करने के लिए कस्टम सत्यापनकर्ता लिखें
  3. वर्किंग उदाहरण https://stackblitz.com/edit/angular-validate-at-least-one-checkbox-was-selected

इसने भी मुझे कभी-कभी मारा, इसलिए मैंने फॉर्मअरे और फॉर्मग्रुप दोनों तरीकों की कोशिश की।

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

मूल रूप से FormArrayइसका एक प्रकार है FormGroup। मुख्य अंतर यह है कि इसका डेटा एक सरणी के रूप में क्रमबद्ध हो जाता है (फॉर्मग्रुप के मामले में ऑब्जेक्ट के रूप में क्रमबद्ध होने के विपरीत)। यह विशेष रूप से उपयोगी हो सकता है जब आप नहीं जानते कि समूह के भीतर गतिशील रूपों की तरह कितने नियंत्रण मौजूद होंगे।

सादगी के लिए, आप के साथ एक सरल उत्पाद बनाने की कल्पना करो

  • एक आवश्यक उत्पाद का नाम टेक्स्टबॉक्स।
  • चयन करने के लिए श्रेणी की एक सूची, कम से कम एक को जांचना आवश्यक है। मान लें कि सूची सर्वर से पुनर्प्राप्त की जाएगी।

सबसे पहले, मैंने केवल उत्पाद नाम formControl के साथ एक फॉर्म सेट किया। यह एक आवश्यक क्षेत्र है।

this.form = this.formBuilder.group({
    name: ["", Validators.required]
});

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

this.getCategories().subscribe(categories => {
    this.form.addControl("categoriesFormArr", this.buildCategoryFormArr(categories));
    this.form.addControl("categoriesFormGroup", this.buildCategoryFormGroup(categories));
})

श्रेणी सूची बनाने के लिए दो दृष्टिकोण हैं।

1. रूप

  buildCategoryFormArr(categories: ProductCategory[], selectedCategoryIds: string[] = []): FormArray {
    const controlArr = categories.map(category => {
      let isSelected = selectedCategoryIds.some(id => id === category.id);
      return this.formBuilder.control(isSelected);
    })
    return this.formBuilder.array(controlArr, atLeastOneCheckboxCheckedValidator())
  }
<div *ngFor="let control of categoriesFormArr?.controls; let i = index" class="checkbox">
  <label><input type="checkbox" [formControl]="control" />
    {{ categories[i]?.title }}
  </label>
</div>

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

यह ध्यान दिया जाता है कि जब आप formArray मानों को एक्सेस करने का प्रयास करते हैं। ऐसा लगेगा [false, true, true]। चयनित आईडी की एक सूची प्राप्त करने के लिए, इसे सूची से जांचने के लिए थोड़ा और काम करने की आवश्यकता थी लेकिन सरणी सूचकांक पर आधारित। मुझे अच्छा नहीं लगता लेकिन यह काम करता है।

get categoriesFormArraySelectedIds(): string[] {
  return this.categories
  .filter((cat, catIdx) => this.categoriesFormArr.controls.some((control, controlIdx) => catIdx === controlIdx && control.value))
  .map(cat => cat.id);
}

इसलिए मैं FormGroupउस मामले के लिए उपयोग कर रहा हूं

2. समूह

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

buildCategoryFormGroup(categories: ProductCategory[], selectedCategoryIds: string[] = []): FormGroup {
  let group = this.formBuilder.group({}, {
    validators: atLeastOneCheckboxCheckedValidator()
  });
  categories.forEach(category => {
    let isSelected = selectedCategoryIds.some(id => id === category.id);
    group.addControl(category.id, this.formBuilder.control(isSelected));
  })
  return group;
}
<div *ngFor="let item of categories; let i = index" class="checkbox">
  <label><input type="checkbox" [formControl]="categoriesFormGroup?.controls[item.id]" /> {{ categories[i]?.title }}
  </label>
</div>

प्रपत्र समूह का मान इस तरह दिखेगा:

{
    "category1": false,
    "category2": true,
    "category3": true,
}

लेकिन अक्सर हम केवल श्रेणी सूची के रूप में प्राप्त करना चाहते हैं ["category2", "category3"]। मुझे इन आंकड़ों को लेने के लिए भी लिखना होगा। मुझे इस दृष्टिकोण को फॉर्मअरे की तुलना में बेहतर लगता है, क्योंकि मैं वास्तव में फॉर्म से ही मूल्य ले सकता था।

  get categoriesFormGroupSelectedIds(): string[] {
    let ids: string[] = [];
    for (var key in this.categoriesFormGroup.controls) {
      if (this.categoriesFormGroup.controls[key].value) {
        ids.push(key);
      }
      else {
        ids = ids.filter(id => id !== key);
      }
    }
    return ids;
  }

3. कम से कम एक चेकबॉक्स की जांच करने के लिए कस्टम सत्यापनकर्ता का चयन किया गया था

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

export function atLeastOneCheckboxCheckedValidator(minRequired = 1): ValidatorFn {
  return function validate(formGroup: FormGroup) {
    let checked = 0;

    Object.keys(formGroup.controls).forEach(key => {
      const control = formGroup.controls[key];

      if (control.value === true) {
        checked++;
      }
    });

    if (checked < minRequired) {
      return {
        requireCheckboxToBeChecked: true,
      };
    }

    return null;
  };
}

6

मुझे यहाँ कोई समाधान नहीं दिखाई देता है जो पूरी तरह से प्रतिक्रियात्मक रूपों का उपयोग करते हुए प्रश्न का पूरी तरह से उत्तर देता है, इसलिए यहाँ मेरा समाधान उसी के लिए है।


सारांश

यहां स्टैक्ब्लिट्ज उदाहरण के साथ विस्तृत विवरण का पिट है।

  1. उपयोग FormArrayचेकबॉक्स के लिए और फ़ॉर्म को इनिशियलाइज़ करें।
  2. valueChangesजब आप फॉर्म को कुछ प्रदर्शित करना चाहते हैं, लेकिन घटक में कुछ और स्टोर करना चाहते हैं, तो यह देखने योग्य है। मैप करें true/false वांछित मूल्यों यहाँ करने के लिए मान।
  3. फ़िल्टर करें falseसबमिट करने के समय मानों को ।
  4. valueChangesअवलोकनीय से असावधान।

StackBlitz उदाहरण


विस्तृत विवरण

फ़ॉर्म को परिभाषित करने के लिए FormArray का उपयोग करें

जैसा कि पहले ही उल्लेखित उत्तर सही है। FormArrayऐसे मामलों में जाने का तरीका है, जहाँ आप डेटा को किसी सरणी में लाना पसंद करेंगे। तो पहली चीज जो आपको करने की ज़रूरत है वह है फॉर्म का निर्माण।

checkboxGroup: FormGroup;
checkboxes = [{
    name: 'Value 1',
    value: 'value-1'
}, {
    name: 'Value 2',
    value: 'value-2'
}];

this.checkboxGroup = this.fb.group({
    checkboxes: this.fb.array(this.checkboxes.map(x => false))
});

यह सिर्फ सभी चेकबॉक्स के प्रारंभिक मूल्य को निर्धारित करेगा false

इसके बाद, हमें टेम्पलेट में इन फॉर्म वेरिएबल्स को रजिस्टर करने की जरूरत है और इन्हें टेम्प्लेट में प्रदर्शित करने के लिए checkboxesऐरे (नॉट FormArrayद चेकबॉक्स डेटा) पर इटर्नेट करें।

<form [formGroup]="checkboxGroup">
    <ng-container *ngFor="let checkbox of checkboxes; let i = index" formArrayName="checkboxes">
        <input type="checkbox" [formControlName]="i" />{{checkbox.name}}
    </ng-container>
</form>

मान का उपयोग करें परिवर्तनशील

यहाँ वह हिस्सा है जो मैंने यहाँ दिए गए किसी उत्तर में नहीं देखा है। इस तरह की स्थितियों में, जहां हम उक्त डेटा प्रदर्शित करना चाहते हैं, लेकिन इसे कुछ और के रूप में संग्रहीत करते हैं, तो valueChangesअवलोकन बहुत उपयोगी है। उपयोग करते हुए valueChanges, हम वांछित डेटा से प्राप्त किए गए / checkboxesऔर फिर / मानों में परिवर्तन का निरीक्षण कर सकते हैं । ध्यान दें कि यह चेकबॉक्स के चयन को नहीं बदलेगा क्योंकि चेकबॉक्स को दिया गया कोई भी सत्य मान इसे चेक किए गए और इसके विपरीत चिह्नित करेगा।maptruefalseFormArray

subscription: Subscription;

const checkboxControl = (this.checkboxGroup.controls.checkboxes as FormArray);
this.subscription = checkboxControl.valueChanges.subscribe(checkbox => {
    checkboxControl.setValue(
        checkboxControl.value.map((value, i) => value ? this.checkboxes[i].value : false),
        { emitEvent: false }
    );
});

मूल रूप FormArrayसे यह मूल checkboxesसरणी में मानों को मैप करता है और valueचेकबॉक्स के रूप में चिह्नित होने पर trueरिटर्न देता है, अन्यथा यह वापस आ जाता है falseemitEvent: falseकी स्थापना के बाद से यहां महत्वपूर्ण है FormArrayबिना यह कारण होगा मूल्य valueChangesएक अंतहीन लूप बनाने एक घटना फेंकना। के लिए सेट emitEventकरके false, हम यह सुनिश्चित कर रहे हैं कि valueChangesजब हम यहां मूल्य निर्धारित करते हैं तो अवलोकन योग्य नहीं निकलता है।

झूठे मूल्यों को छान डालो

हम सीधे falseमानों को फ़िल्टर नहीं कर सकते FormArrayक्योंकि ऐसा करने से टेम्पलेट गड़बड़ हो जाएगा क्योंकि वे चेकबॉक्स से बंधे हैं। तो सबसे अच्छा संभव समाधान falseप्रस्तुत करने के दौरान मूल्यों को फ़िल्टर करना है । ऐसा करने के लिए प्रसार ऑपरेटर का उपयोग करें।

submit() {
    const checkboxControl = (this.checkboxGroup.controls.checkboxes as FormArray);
    const formValue = {
        ...this.checkboxGroup.value,
        checkboxes: checkboxControl.value.filter(value => !!value)
    }
    // Submit formValue here instead of this.checkboxGroup.value as it contains the filtered data
}

यह मूल रूप से मिथ्या मूल्यों को छानता है checkboxes

मान चेंजेज से अनसब्सक्राइब करें

अंत में, से सदस्यता समाप्त करने के लिए मत भूलना valueChanges

ngOnDestroy() {
    this.subscription.unsubscribe();
}

नोट: एक विशेष मामला है जहां मान सेट नहीं किया जा सकता FormArrayहै valueChanges, यानी यदि चेकबॉक्स मान संख्या पर सेट है 0। इससे यह लगेगा कि चेकबॉक्स का चयन नहीं किया जा सकता है क्योंकि चेकबॉक्स का चयन FormControlनंबर 0(एक गलत मान) के रूप में सेट करेगा और इसलिए इसे अनियंत्रित रखें। यह 0मान के रूप में संख्या का उपयोग नहीं करने के लिए पसंद किया जाएगा, लेकिन अगर यह आवश्यक है, तो आपको सशर्त रूप 0से कुछ सत्य मान पर सेट करना होगा, स्ट्रिंग '0'या बस सादा trueऔर फिर सबमिट करने पर, इसे वापस संख्या में परिवर्तित करें 0

StackBlitz उदाहरण

StackBlitz के पास उस कोड के लिए भी है जब आप डिफ़ॉल्ट मानों को चेकबॉक्स में भेजना चाहते हैं, ताकि वे UI में जाँच के रूप में चिह्नित हो जाएं।


4

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

component.html

<form [formGroup]="customForm" (ngSubmit)="onSubmit()">
    <div class="form-group" *ngFor="let parameter of parameters"> <!--I iterate here to list all my checkboxes -->
        <label class="control-label" for="{{parameter.Title}}"> {{parameter.Title}} </label>
            <div class="checkbox">
              <input
                  type="checkbox"
                  id="{{parameter.Title}}"
                  formControlName="{{parameter.Title}}"
                  (change)="onCheckboxChange($event)"
                  > <!-- ^^THIS^^ is the important part -->
             </div>
      </div>
 </form>

component.ts

onCheckboxChange(event) {
    //We want to get back what the name of the checkbox represents, so I'm intercepting the event and
    //manually changing the value from true to the name of what is being checked.

    //check if the value is true first, if it is then change it to the name of the value
    //this way when it's set to false it will skip over this and make it false, thus unchecking
    //the box
    if(this.customForm.get(event.target.id).value) {
        this.customForm.patchValue({[event.target.id] : event.target.id}); //make sure to have the square brackets
    }
}

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


यह मुझे सही रास्ते पर ले गया, मैंने इसे समाप्त कर दिया। इस CustomForm.patchValue ({[event.target.id]: event.target.checked});
डिमोड्वे

4

यदि आप कोणीय प्रतिक्रियाशील रूप ( https://angular.io/guide/reactive-forms ) का उपयोग करना चाहते हैं ।

चेकबॉक्स के समूह के आउटपुट मूल्य का प्रबंधन करने के लिए आप एक फॉर्म कंट्रोल का उपयोग कर सकते हैं।

अंग

import { Component } from '@angular/core';
import { FormGroup, FormControl } from '@angular/forms';
import { flow } from 'lodash';
import { flatMap, filter } from 'lodash/fp';

@Component({
  selector: 'multi-checkbox',
  templateUrl: './multi-checkbox.layout.html',
})
export class MultiChecboxComponent  {

  checklistState = [ 
      {
        label: 'Frodo Baggins',
        value: 'frodo_baggins',
        checked: false
      },
      {
        label: 'Samwise Gamgee',
        value: 'samwise_gamgee',
        checked: true,
      },
      {
        label: 'Merry Brandybuck',
        value: 'merry_brandybuck',
        checked: false
      }
    ];

  form = new FormGroup({
    checklist : new FormControl(this.flattenValues(this.checklistState)),
  });


  checklist = this.form.get('checklist');

  onChecklistChange(checked, checkbox) {
    checkbox.checked = checked;
    this.checklist.setValue(this.flattenValues(this.checklistState));
  }

  flattenValues(checkboxes) {
    const flattenedValues = flow([
      filter(checkbox => checkbox.checked),
      flatMap(checkbox => checkbox.value )
    ])(checkboxes)
    return flattenedValues.join(',');
  }
}

एचटीएमएल

<form [formGroup]="form">
    <label *ngFor="let checkbox of checklistState" class="checkbox-control">
    <input type="checkbox" (change)="onChecklistChange($event.target.checked, checkbox)" [checked]="checkbox.checked" [value]="checkbox.value" /> {{ checkbox.label }}
  </label>
</form>

checklistState

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

नमूना:

{
   label: 'Value 1',
   value: 'value_1',
   checked: false
},
{
  label: 'Samwise Gamgee',
  value: 'samwise_gamgee',
  checked: true,
},
{
  label: 'Merry Brandybuck',
  value: 'merry_brandybuck',
  checked: false
}

checklist प्रपत्र नियंत्रण

यह नियंत्रण स्टोर को मान के रूप में सहेजना चाहता है

मूल्य उत्पादन: "value_1,value_2"

Https://stackblitz.com/edit/angular-multi-checklist पर डेमो देखें


आसानी से मेरे लिए सबसे अच्छा समाधान। बहुत बहुत धन्यवाद।
न्यूक्लिक

2

मेरा समाधान - सामग्री दृश्य के साथ कोणीय 5 के लिए इसे हल किया
गया है

formArrayName = "अधिसूचना"

(परिवर्तन) = "updateChkbxArray (n.id, $ event.checked, 'सूचना')"

इस तरह यह एक रूप में कई चेकबॉक्स सरणियों के लिए काम कर सकता है। हर बार कनेक्ट करने के लिए नियंत्रण सरणी का नाम सेट करें।

constructor(
  private fb: FormBuilder,
  private http: Http,
  private codeTableService: CodeTablesService) {

  this.codeTableService.getnotifications().subscribe(response => {
      this.notifications = response;
    })
    ...
}


createForm() {
  this.form = this.fb.group({
    notification: this.fb.array([])...
  });
}

ngOnInit() {
  this.createForm();
}

updateChkbxArray(id, isChecked, key) {
  const chkArray = < FormArray > this.form.get(key);
  if (isChecked) {
    chkArray.push(new FormControl(id));
  } else {
    let idx = chkArray.controls.findIndex(x => x.value == id);
    chkArray.removeAt(idx);
  }
}
<div class="col-md-12">
  <section class="checkbox-section text-center" *ngIf="notifications  && notifications.length > 0">
    <label class="example-margin">Notifications to send:</label>
    <p *ngFor="let n of notifications; let i = index" formArrayName="notification">
      <mat-checkbox class="checkbox-margin" (change)="updateChkbxArray(n.id, $event.checked, 'notification')" value="n.id">{{n.description}}</mat-checkbox>
    </p>
  </section>
</div>

अंत में आपको मूल रिकॉर्ड आईडी के साथ सेव / अपडेट करने के लिए फॉर्म को सेव करना है। यूआई देखें

फॉर्म के जोंस का प्रासंगिक हिस्सा

सुधार के लिए कोई टिप्पणी करने में खुशी होगी।


0

टेम्पल पार्ट: -

    <div class="form-group">
         <label for="options">Options:</label>
         <div *ngFor="let option of options">
            <label>
                <input type="checkbox"
                   name="options"
                   value="{{option.value}}"
                   [(ngModel)]="option.checked"
                                />
                  {{option.name}}
                  </label>
              </div>
              <br/>
         <button (click)="getselectedOptions()"  >Get Selected Items</button>
     </div>

नियंत्रण भाग: -

        export class Angular2NgFor {

          constructor() {
             this.options = [
              {name:'OptionA', value:'first_opt', checked:true},
              {name:'OptionB', value:'second_opt', checked:false},
              {name:'OptionC', value:'third_opt', checked:true}
             ];


             this.getselectedOptions = function() {
               alert(this.options
                  .filter(opt => opt.checked)
                  .map(opt => opt.value));
                }
             }

        }

1
Hi @EchoLogic .. कृपया मुझे किसी भी प्रश्न के मामले में बताएं
अभिषेक श्रीवास्तव

1
यह ReactiveForms का उपयोग नहीं कर रहा है, लेकिन नियमित रूप से इस प्रश्न का उत्तर नहीं देता है
Guillaume

0

मेरे 5 सेंट जोड़ें) मेरा प्रश्न मॉडल

{
   name: "what_is_it",
   options:[
     {
      label: 'Option name',
      value: '1'
     },
     {
      label: 'Option name 2',
      value: '2'
     }
   ]
}

template.html

<div class="question"  formGroupName="{{ question.name }}">
<div *ngFor="let opt of question.options; index as i" class="question__answer" >
  <input 
    type="checkbox" id="{{question.name}}_{{i}}"
    [name]="question.name" class="hidden question__input" 
    [value]="opt.value" 
    [formControlName]="opt.label"
   >
  <label for="{{question.name}}_{{i}}" class="question__label question__label_checkbox">
      {{opt.label}}
  </label>
</div>

component.ts

 onSubmit() {
    let formModel = {};
    for (let key in this.form.value) {
      if (typeof this.form.value[key] !== 'object') { 
        formModel[key] = this.form.value[key]
      } else { //if formgroup item
        formModel[key] = '';
        for (let k in this.form.value[key]) {
          if (this.form.value[key][k])
            formModel[key] = formModel[key] + k + ';'; //create string with ';' separators like 'a;b;c'
        }
      }
    }
     console.log(formModel)
   }

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.