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