কৌণিক প্রতিক্রিয়াশীল ফোরাম: চেকবক্স মানগুলির একটি অ্যারে উত্পাদন করছে?


109

একই সাথে আবদ্ধ চেকবাক্সগুলির একটি তালিকা দেওয়া formControlName, আমি কীভাবে formControlকেবল true/ এর পরিবর্তে আবদ্ধ চেকবক্স মানগুলির একটি অ্যারে উত্পাদন করতে পারি false?

উদাহরণ:

<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', ...]

আপনি কি কোন সমাধান খুঁজে পেয়েছেন?
সিপি

এটি সম্ভবত কোনও ফর্মের মধ্যে চেকবক্সগুলি করার সবচেয়ে বেশি ইঞ্জিনিয়ারড উপায়। এটি মোটেই সহজ নয়।
মিউলসন

8
কৌণিক। আমি যা করার চেষ্টা করছি তা হ'ল আমার প্রতিক্রিয়াশীল আকারে বাঁধতে একটি মাদুর-রেডিও-গ্রুপ পাওয়া। কৌণিক নিয়ে এত লড়াই করা আমার মনে নেই। সমস্ত নিবন্ধ একই জিনিস ইঙ্গিত করছে। এটি কাজ করতে পারে না। অন্য সব কিছুই খুব সোজা is আমি সম্ভবত এটি দীর্ঘ দীর্ঘ দিকে তাকিয়ে ছিলাম। তবুও কেবল কোনও ফর্মের অ্যারের মানের জন্য খুব বেশি জটিলতার মতো মনে হচ্ছে।
মিউলসন

4
হ্যাঁ এটা যখন আমি 2016 সালে এই জিজ্ঞাসা ভয়ানক ছিল, এবং এটি এখনও 2019. ভয়ানক
ReactingToAngularVues

4
আমি এই প্রশ্নে একটি টন যোগ করছি না, তবে আমি এটি অন্যদের কাছে জানতে চাই যে আমিও একইভাবে অনুভব করি। এই একা কৌণিক প্রতিক্রিয়াশীল ফর্ম শেখার সবচেয়ে শক্ত অংশ ছিল। আমার মনে হচ্ছে এটি মোটেও কঠিন হওয়া উচিত নয়। যদিও আমি লড়াইয়ে একা নই তা দেখে আমি খুশি। সুতরাং প্রশ্ন পোস্ট করার জন্য ধন্যবাদ।
নর্থস্টারকোড

উত্তর:


55

সিল্যান্টসোড উত্তরের সাহায্যে, আমি আমার ফর্ম বিল্ডারে রাষ্ট্রগুলির পরিবর্তে মানগুলি পেতে একটি সমাধান লিখেছিলাম।

আমি ফর্মআরেতে মানগুলি যুক্ত করতে বা মুছে ফেলার জন্য একটি পদ্ধতি ব্যবহার করি। এটি একটি খারাপ পদ্ধতির হতে পারে, তবে এটি কার্যকর!

উপাদান। 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>

घटक.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']

কেবলমাত্র একটি জিনিস অনুপস্থিত, ফর্মআরাই পূরণ করার জন্য একটি ফাংশন যদি আপনার মডেল ইতিমধ্যে মানগুলি পরীক্ষা করে।


আপনার উদাহরণটি ডিবিতে প্রবেশ করার পরে ডেটা লোড করার সময় আমার চেকবক্সটি চেক করা হয় কিনা তা আমি কীভাবে চেক করব?
ডিভোরা

এই সমাধানটিতে সর্বদা ফর্মটি বৈধ হচ্ছে এমনকি যদি চেকবক্সটি নির্বাচন না করা হয়
তেজ

myChoices: new FormArray([], Validators.required)
বিক্রম নাথ

"কিন্তু এটি কাজ করে!" প্রযুক্তি debtণ কিভাবে শুরু হয়। এটি এটি করার প্রতিক্রিয়াশীল ফর্ম উপায় নয়। প্রতিটি চেকবক্স ইনপুটটিতে ফর্মকন্ট্রোলগুলি ব্যবহার করার একটি সুবিধা হ'ল আপনি তাদের ডিওমে পুনরায় যুক্ত করার পরেও তাদের রাষ্ট্রগুলি মনে রাখতে পারেন।
এমআইডব্লিউএমআইবি

51

Https://angular.io/docs/ts/latest/api/forms/index/FormArray-class.html ব্যবহার করার জন্য এখানে একটি ভাল জায়গাFormArray

শুরু করতে আমরা আমাদের নিয়ন্ত্রণগুলির অ্যারে তৈরি করব একটি হয় FormBuilderবা নতুন করে আপ দিয়েFormArray

ফর্ম বিল্ডার

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
});

করার মতো যথেষ্ট সহজ, তবে তারপরে আমরা আমাদের টেম্পলেটটি পরিবর্তন করতে যাচ্ছি এবং টেম্প্লেটিং ইঞ্জিনটি কীভাবে আমাদের নিয়ন্ত্রণগুলিতে আবদ্ধ করব তা পরিচালনা করতে দেব:

টেম্পলেট। 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=preview প্রায় অকর্মা


4
সম্ভবত আপনার id = "xxx" মুছে ফেলা উচিত, আইডিটি কি অনন্য হওয়া উচিত?
পেইসং শাওনগ

4
আইডি জন্য সূচক ব্যবহার করা যেতে পারে *ngFor="let control of checkboxGroup.controls['myValues'].controls ; let i=index""
মির্জা

9
এটি দুর্দান্ত, তবে চেকবাক্সগুলির সম্পূর্ণ জেনেরিক অ্যারে তৈরি করে। সম্ভবত আপনি কোনও অ্যারে বা অন্য কোনও কিছুতে লোড করছেন এবং প্রতিটি চেকবক্সকে অন্য কোনও মানের সাথে সংযুক্ত করছেন। উদাহরণস্বরূপ, প্রতিটি ফর্ম নিয়ন্ত্রণে ফর্ম লেবেলে ব্যবহারের জন্য কোনও পাঠ্য স্ট্রিং কীভাবে যুক্ত করবেন?
Askdesigners

এনএম আমি এটিকে সবেমাত্র একটি বাহ্যিক অ্যারের পাশে ম্যাপ করেছি: পি
এসকডিজাইনার

@ এসকিডিজাইনার্স আপনি কি চেকবক্স এবং লেবেলগুলি রাখতে নিজের সমাধান পোস্ট করতে পারেন?
এডিজিক

27

পূর্ববর্তী সংস্করণগুলির চেয়ে এঙ্গুলার 6 এ এটি করা উল্লেখযোগ্যভাবে সহজ, এমনকি যদি কোনও এপিআই থেকে চেকবক্সের তথ্য অবিচ্ছিন্নভাবে পপ করা হয়।

অনুধাবন করার জন্য প্রথম জিনিসটি হ'ল কৌণিক 6 এর keyvalueপাইপকে ধন্যবাদ আমাদের FormArrayআর ব্যবহার করার দরকার নেই, এবং এর পরিবর্তে বাসা বাঁধতে পারে FormGroup

প্রথমে ফর্ম বিল্ডারটি কনস্ট্রাক্টরে পাস করুন

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>

4
চেকবক্স মানগুলির একটি সহজ হার্ডকোডযুক্ত অ্যারের ক্ষেত্রেও খুব ব্যবহারযোগ্য। তারপরে আপনি সরাসরি এনজিওআইনিট () এ লুপের জন্য অনুরূপ ব্যবহার করে ফর্ম নিয়ন্ত্রণগুলি যুক্ত করতে পারেন এবং আপনার ফর্মের চেকবক্সগুলি চেকবক্স মানগুলির অ্যারেটিকে গতিশীলভাবে প্রতিফলিত করবে
আর্জন

4
এটি এখনও অবলম্বন করে [কী 1 = সত্য, কী 2 = মিথ্যা, কী 3 = সত্য]। আমরা ['কী 1', 'কী 3'] চাই
এফ.খ্যান্তিসিস

@ f.khantsis আপনি এটির মতো এটি করতে পারেন: `কনট মান = {কী 1: সত্য, কী 2: মিথ্যা, কী 3: সত্য}; কনস্ট লিস্ট = অবজেক্ট.এন্ট্রি (মান)। ফিল্টার (([_, isSelected]) => isSelected)। ম্যাপ (([কী]) => কী); কনসোল.লগ (তালিকা); `
zauni

4
সেরা সমাধান 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);}
 }

প্রতিটি চেকবাক্সকে এমন একটি উপাদান থেকে তৈরি ফর্মগ্রুপ হিসাবে দেখা যাক যার একমাত্র সম্পত্তি চেকবক্সের মান।

 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>

7

আমি এখানে এমন কোনও সমাধান দেখতে পাচ্ছি না যা সম্পূর্ণরূপে প্রতিক্রিয়াশীল ফর্মগুলি ব্যবহার করে প্রশ্নের সম্পূর্ণরূপে উত্তর দেয় তাই এর জন্য এখানে আমার সমাধান's


সারসংক্ষেপ

স্ট্যাকব্লিটজ উদাহরণ সহ বিশদ ব্যাখ্যার মঞ্চ এখানে।

  1. FormArrayচেকবাক্সগুলির জন্য ব্যবহার করুন এবং ফর্মটি আরম্ভ করুন।
  2. valueChangesলক্ষণীয় যখন আপনি প্রদর্শন কিছু কিন্তু কম্পোনেন্ট অন্য দোকান কিছু ফর্ম চান তাদের জন্য নির্ভুল। মানচিত্র true/ falseপছন্দসই মান এখানে মান।
  3. falseজমা দেওয়ার সময় মানগুলি ফিল্টার করুন ।
  4. valueChangesপর্যবেক্ষণযোগ্য থেকে সাবস্ক্রাইব করুন ।

স্ট্যাকব্লিটজ উদাহরণ


বিস্তারিত ব্যাখ্যা

ফর্মটি সংজ্ঞায়িত করতে ফর্মআরে ব্যবহার করুন

উত্তর হিসাবে ইতিমধ্যে সঠিক হিসাবে চিহ্নিত হিসাবে উল্লেখ করা হয়েছে। 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

স্ট্যাকব্লিটজ উদাহরণ

আপনি যখন চেকবক্সগুলিতে ডিফল্ট মানগুলি পাস করতে চান তখন স্ট্যাকব্লিটজের কোডও রয়েছে যাতে তারা ইউআই-তে চেকড হিসাবে চিহ্নিত হয়।


এটির জন্য এখনও দুটি অ্যারে বজায় রাখা এবং সেগুলি সিঙ্কে রাখা দরকার। আমি যতটা আশা করছি তত পরিষ্কার নয়। সম্ভবত আমরা দুটি অ্যারে না রেখে জটিল মানগুলি ধরে রাখতে ফর্ম নিয়ন্ত্রণগুলি পেতে পারি।
এমআইডব্লিউএমআইবি

4
জটিল মান কাজ করে না কারণ মানটি চেকবাক্সের জন্য সত্য বা মিথ্যা হতে হবে। সুতরাং এই সমাধানটি এখনও সেরা দেখাচ্ছে।
এমআইডব্লিউএমআইবি

6

টিএল; ডিআর

  1. আমি চেকবক্সের তালিকাটি জনপ্রিয় করতে ফর্মগ্রুপ ব্যবহার করতে পছন্দ করি
  2. চেক করার জন্য একটি কাস্টম ভ্যালিডিটার লিখুন কমপক্ষে একটি চেকবক্স নির্বাচন করা হয়েছিল
  3. কাজের উদাহরণ https://stackblitz.com/edit/angular-uthorate-at-least-one-checkbox-was-selected

এটি আমার মাঝে মাঝে আঘাত করেছিল তাই আমি ফর্মআরাই এবং ফর্মগ্রুপ উভয় পদ্ধতির চেষ্টা করেছিলাম।

বেশিরভাগ সময়, চেকবক্সের তালিকাটি সার্ভারে পপুলেটেড ছিল এবং আমি এটিআইপি-র মাধ্যমে পেয়েছি। তবে কখনও কখনও আপনার পূর্বনির্ধারিত মান সহ চেকবক্সের একটি স্ট্যাটিক সেট থাকবে have প্রতিটি ব্যবহারের ক্ষেত্রে, সম্পর্কিত ফর্মআরাই বা ফর্মগ্রুপ ব্যবহার করা হবে।

মূলত FormArrayএর একটি বৈকল্পিক FormGroup। মূল পার্থক্যটি হ'ল এর ডেটা অ্যারে হিসাবে সিরিয়ালাইজড হয় (ফর্মগ্রুপের ক্ষেত্রে অবজেক্ট হিসাবে সিরিয়ালাইজড হওয়ার বিপরীতে)। এটি বিশেষত কার্যকর হতে পারে যখন আপনি জানেন না যে গতিশীল ফর্মগুলির মতো গ্রুপের মধ্যে কতগুলি নিয়ন্ত্রণ উপস্থিত থাকবে।

সরলতার স্বার্থে, কল্পনা করুন আপনার সাথে একটি সাধারণ তৈরি পণ্য ফর্ম রয়েছে

  • এক প্রয়োজনীয় পণ্যের নাম পাঠ্যবাক্স।
  • বিভাগ থেকে নির্বাচন করার জন্য একটি তালিকা, কমপক্ষে একটি চেক করা প্রয়োজন। ধরে নিন যে তালিকাটি সার্ভার থেকে পুনরুদ্ধার করা হবে।

প্রথমত, আমি কেবলমাত্র পণ্যের নাম ফর্মকন্ট্রোল সহ একটি ফর্ম সেট আপ করেছি। এটি প্রয়োজনীয় ক্ষেত্র।

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 আমাকে ফর্মআরে ফিরিয়ে দেবে। এটি আর্গুমেন্ট হিসাবে নির্বাচিত মানের একটি তালিকাও গ্রহণ করে তাই আপনি যদি ডেটা সম্পাদনা করার জন্য ফর্মটি পুনরায় ব্যবহার করতে চান তবে এটি সহায়ক হতে পারে। একটি নতুন পণ্য ফর্ম তৈরি করার উদ্দেশ্যে, এটি এখনও প্রযোজ্য নয়।

উল্লেখ্য যে আপনি যখন ফর্মআরে মানগুলি অ্যাক্সেস করার চেষ্টা করবেন তখন। এটা দেখতে হবে [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এই বিষয়টির জন্য ব্যবহার করে এসেছি

২. ফর্ম গ্রুপ

ফর্মগ্রুপের ভিন্নতা হ'ল এটি ফর্ম ডেটাটিকে অবজেক্ট হিসাবে সংরক্ষণ করবে, যার জন্য একটি কী এবং ফর্ম নিয়ন্ত্রণ প্রয়োজন। সুতরাং কীটিটি বিভাগের মতো হিসাবে সেট করা ভাল ধারণা এবং তারপরে আমরা পরে এটি পুনরুদ্ধার করতে পারি।

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;
  }

৩. কমপক্ষে একটি চেকবক্স চেক করতে কাস্টম যাচাইকারী নির্বাচন করা হয়েছিল

আমি অন্তত এক্স চেকবক্সটি নির্বাচন করার জন্য যাচাইকারী তৈরি করেছি, ডিফল্টরূপে এটি কেবল একটি চেকবাক্সের বিরুদ্ধে চেক করবে।

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;
  };
}

4

এটি ক্লিক করার পরে একটি ইভেন্ট তৈরি করুন এবং তারপরে চেক বাক্সটি যা উপস্থাপন করে তার নামে ম্যানুয়ালি সত্যের মান পরিবর্তন করে, নাম বা সত্যটি একই মূল্যায়ন করবে এবং আপনি সত্য / মিথ্যা তালিকার পরিবর্তে সমস্ত মান পেতে পারেন। প্রাক্তন:

উপাদান। 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>

घटक.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
    }
}

এটি ইতিমধ্যে কৌণিক ফর্মগুলির দ্বারা সত্য বা মিথ্যা হিসাবে পরিবর্তিত হওয়ার পরে এই ইভেন্টটি ধরা পড়ে, যদি সত্য হয় তবে আমি নামটি চেকবক্সটি উপস্থাপন করে তার নামে পরিবর্তন করি, যা প্রয়োজন হলে সত্য / মিথ্যা হিসাবে যাচাই করা হয় যদি সত্যকেও মূল্যায়ন করা হয় আমরা হব.


এটি আমাকে সঠিক পথে পেয়েছে, আমি এই কাস্টমফর্ম.প্যাচভ্যালু ({[ইভেন্ট.target.id]: ইভেন্ট.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-m Multi-checklist এ ডেমো দেখুন


আমার জন্য সহজেই সেরা সমাধান। তোমাকে অনেক ধন্যবাদ.
নিউক্লিক

2

আমার সমাধান - ম্যাটেরিয়াল ভিউ সহ কৌনিক 5 এর জন্য এটি সমাধান হয়েছে
সংযোগটি এর মধ্য দিয়ে

formArrayName = "বিজ্ঞপ্তি"

(পরিবর্তন) = "updateChkbxArray (n.id, $ ইভেন্ট.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));
                }
             }

        }

4
হাই @ ইকোলজিক .. দয়া করে কোনও প্রশ্নের ক্ষেত্রে আমাকে জানাবেন
অভিষেক শ্রীবাস্তব

4
এটি রিঅ্যাকটিভ ফর্মগুলি ব্যবহার করছে না তবে নিয়মিত ফর্মগুলি তাই প্রশ্নের উত্তর দেয় না
গিলিয়াম

0

আমার 5 সেন্ট যোগ করুন) আমার প্রশ্ন মডেল

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

টেম্পলেট। 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>

घटक.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)
   }

0

@ ন্যাশ 11 এর সম্পর্কিত উত্তর, আপনি কীভাবে চেকবক্স মানগুলির একটি অ্যারে উত্পাদন করবেন তা এখানে

এবং

একটি চেকবক্স রয়েছে যা সমস্ত চেকবাক্স নির্বাচন করে:

https://stackblitz.com/edit/angular-checkbox-custom-value-with-selectall

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.