الزاوي: إنشاء مكون خانة اختيار متعددة مناسبة لإعادة الاستخدام

لنقم بإنشاء مكون الزاوي لإنشاء مجموعة من مربعات الاختيار من مجموعة منطقية محددة. سيتم كتابة المكون بأفكار إعادة الاستخدام. ماذا يعني هذا؟ هنا مثال أدناه:

تخيل أن لديك مهمة تعديل المستخدمين. عند التحرير ، عادةً ما يتم فتح نموذج يحتوي على جميع الحقول. يمكن للمستخدم أن يكون له دور واحد أو أكثر من قائمة "Adimin" و "Director" و "Professor" و "Student".

لتنفيذ خيارات متعددة للأدوار ، تقرر الرسم على مربع اختيار واحد لكل دور. عن طريق تحديد أو إلغاء تحديد أدوار المستخدم ستتغير.

أولاً ، لننشئ مكونًا أصلًا (أي صفحة للنموذج) والذي سيحتوي بالفعل على مكون مجموعة مربعات الاختيار .

export class AppComponent implements OnInit { private userRoles = [ { id: 1, name: 'Admin' }, { id: 2, name: 'Director' }, { id: 3, name: 'Professor' }, { id: 4, name: 'Student' } ]; public userModel = { id: 0, name: "", roles: [] }; constructor() { } ngOnInit(): void { } } 

كما ترى هنا ، قمت بعمل كود ثابت لجميع الأدوار الممكنة ، ولكن في تطبيق حقيقي ، من المرجح أن يتم طلب الأدوار من قاعدة البيانات. من أجل محاكاة HTTP الخاص بنا إلى الخادم ، قمت بتعيين نفس القيم لمتغير آخر مع تأخير طفيف.

 //app.component.ts userRolesOptions = new Array<any>(); ngOnInit(): void { setTimeout(() => { this.userRolesOptions = this.userRoles; }, 1000); //     1  } 

لنبدأ الآن في إنشاء مكون مجموعة مربعات الاختيار المعمم ، والذي يمكن إعادة استخدامه دون أي مشاكل في جميع الحالات عند الحاجة إلى مجموعة من مربع الاختيار.

أولاً نحن بحاجة إلى مثل هذه الفئة CheckboxItem.ts

 export class CheckboxItem { value: string; label: string; checked: boolean; constructor(value: any, label: any, checked?: boolean) { this.value = value; this.label = label; this.checked = checked ? checked : false; } } 

سيتم استخدامه بواسطة CheckboxComponent لتقديم جميع الخيارات الممكنة (في حالتنا ، هذه هي الأدوار) وحفظها من الحالة (يتم تحديد الخيار أم لا). لاحظ أن الخاصية "المحددة" هي معلمة اختيارية في المُنشئ وستكون افتراضيًا على false ، أي أنه لن يتم تحديد جميع القيم أولاً. هذا مناسب عندما نقوم بإنشاء مستخدم جديد بدون دور واحد.

بعد ذلك ، سنقوم بتعديل طفيف لمحاكاة طلب الخادم ، حتى نتمكن من التعيين بين استجابة JSON و Array
 userRolesOptions = new Array<CheckboxItem>(); ngOnInit(): void { setTimeout(() => { this.userRolesOptions = this.userRoles.map(x => new CheckboxItem(x.id, x.name)); }, 1000); } 

لا يهم أي هيكل JSON يعود إليه الخادم. تحتوي كل خانة اختيار HTML دائمًا على قيمة ووصف. في حالتنا ، نقوم بتعيين "id" مع "value" و "name" مع "label". سيتم استخدام القيمة كمفتاح أو معرف للخيار ، والتسمية مجرد سلسلة وصف يقرأها المستخدم.

الخطوة التالية هي إنشاء CheckboxGroupComponent. يبدو مثل هذا:

 @Component({ selector: 'checkbox-group', templateUrl: './checkbox-group.component.html', styleUrls: ['./checkbox-group.component.css'] }) export class CheckboxGroupComponent implements OnInit { @Input() options = Array<CheckboxItem>(); constructor() { } ngOnInit() {} } 

هذا ليس برنامجًا تعليميًا الزاويًا ، لذلك لن أشرح تفاصيل إطار العمل. من يحتاج إلى القراءة في الوثائق الرسمية.

ستحتوي الخاصية Input التي تسمى خيارات على قائمة بجميع القيم الممكنة التي لم يتم تحديدها بشكل افتراضي. سيعرض قالب مكون HTML عدد مربعات الاختيار كما تحتوي هذه القائمة.

هذا هو html لـ CheckboxGroupComponent:

 <div *ngFor=”let item of options”> <input type=”checkbox” [(ngModel)]=”item.checked”>{{item.label}} </div> 

لاحظ أنني استخدمت ngModel لربط كل خاصية عنصر "محدد" من قائمة الخيارات .

الخطوة الأخيرة هي إضافة المكون الذي تم إنشاؤه حديثًا إلى قالب AppComponent الأصلي.

 // somewhere in AppComponent html template <checkbox-group [options]=”userRolesOptions”></checkbox-group> 

يجب أن تكون النتيجة كما يلي:

الصورة

للحصول على جميع الخيارات المحددة حاليًا ، سنقوم بإنشاء حدث إخراج والذي ، مع أي نقرة على أحد مربعات الاختيار ، سيعرض قائمة الخيارات المحددة لدينا. شيء من هذا القبيل: [1،2،4]

في قالب CheckboxGroupComponent ، نقوم بربط حدث التغيير مع الوظيفة الجديدة.

 <div *ngFor=”let item of options”> <input type=”checkbox” [(ngModel)]=”item.checked” (change)=”onToggle()”>{{item.label}} </div> 

لقد حان الوقت لتنفيذ هذه الوظيفة بالذات:

 export class CheckboxGroupComponent implements OnInit { @Input() options = Array<CheckboxItem>(); @Output() toggle = new EventEmitter<any[]>(); constructor() {} ngOnInit(){} onToggle() { const checkedOptions = this.options.filter(x => x.checked); this.selectedValues = checkedOptions.map(x => x.value); this.toggle.emit(checkedOptions.map(x => x.value)); } } 

اشترك في هذا الحدث (خاصية الإخراج مع تبديل الاسم) في قالب AppComponent.

 <checkbox-group [options]=”userRolesOptions” (toggle)=”onRolesChange($event)”></checkbox-group> 

وتعيين نتيجة الإرجاع (الأدوار المحددة) في userModel.

 export class CheckboxGroupComponent implements OnInit { //..  onRolesChange(value) { this.userModel.roles = value; console.log('Model role:' , this.userModel.roles); } } 

الآن في كل نقرة على مربع الاختيار سترى قائمة بالأدوار المحددة في وحدة التحكم. بتعبير أدق ، معرفهم. على سبيل المثال ، إذا اخترت الأدوار المشرف والأستاذ ، أحصل على "الأدوار النموذجية: (2) [1 ، 3]".

المكون شبه كامل وجاهز لإعادة الاستخدام. آخر شيء متبقي هو تقديم دعم تهيئة مجموعة مربع الاختيار. ستكون هناك حاجة لذلك في حالة قيامنا بتحرير المستخدم. قبل ذلك ، نحتاج إلى تقديم طلب إلى الخادم للحصول على القائمة الحالية لأدوار المستخدم وتهيئة CheckboxGroupComponent.

لدينا طريقتان للقيام بذلك. الأول هو استخدام مُنشئ فئة CheckboxItem واستخدام المعلمة "المحددة" الاختيارية. في المكان الذي قمنا فيه برسم الخرائط.

 //AppComponent.ts setTimeout(() => { this.userRolesOptions = this.userRoles.map(x => new CheckboxItem(x.id, x.name, true)); }, 1000); //          

الطريقة الثانية هي إضافة قائمة أخرى من القيم المحددة لتهيئة المكون الخاص بنا.

 <checkbox-group [options]=”userRolesOptions” [selectedValues]=”userModel.roles” (toggle)=”onRolesChange($event)”></checkbox-group> 

دعنا نتخيل أننا قدمنا ​​بالفعل طلبًا للمستخدم الحالي وقد أتى نموذج من ثلاثة أدوار من قاعدة البيانات.

 //AppComponent.ts public userModel = { id: 1, name: 'Vlad', roles: [1,2,3] }; constructor() { } //rest of the code 

في CheckboxGroupComponent ، نقوم بتهيئة جميع الخصائص "المحددة" لكل خانة اختيار إلى true إذا كان معرف الدور موجودًا في قائمة القيم المحددة .

 //CheckboxGroupComponent.ts ngOnInit() { this.selectedValues.forEach(value => { const element = this.options.find(x => x.value === value); if (element) { element.checked = true; } }); } 

نتيجة لذلك ، يجب أن تحصل على النتيجة التالية:

الصورة
هنا استخدمت الأنماط من Angular Material

عند بدء التشغيل ، سيكون هناك تأخير لمدة ثانية واحدة قبل أن تقوم Angular برسم جميع مربعات الاختيار على الصفحة. هذا يحاكي الوقت المستغرق في تحميل الأدوار من قاعدة البيانات.

من المهم ملاحظة أنه يمكنك الحصول على جميع الأدوار المحددة من خلال الاشتراك في حدث (تبديل) أو ببساطة استخدام الخاصية "المحددة" في كل عنصر عنصر من قائمة userRolesOptions الموجودة في المكون الرئيسي . هذا لأن الرابط إلى القائمة يتم تمريره عبرInput (ربط) وستتم مزامنة جميع التغييرات داخل الكائن.

 const checkedOptions = this.userRolesOptions.filter(x => x.checked); 

يمكن تصميم مثل هذا المكون كما تريد واستخدامه لأية مهمة حيث هناك حاجة إلى التحديد المتعدد.

شكرا لقراءة هذا المقال! آمل أن تكون قد استمتعت بصنع المكون الزاوي لأفكار إعادة الاستخدام.

ملاحظة: إذا كانت المقالة شائعة ، فسأقوم بنشر الجزء الصغير الثاني ، حيث تمت كتابة نفس المثال باستخدام أشكال تفاعلية الزاوي.

Source: https://habr.com/ru/post/ar417137/


All Articles