کامپوننت دکمه با قابلیت استفاده مجدد در انگولار — از صفر تا صد

آخرین به‌روزرسانی: ۱۴ دی ۱۳۹۸
زمان مطالعه: ۳ دقیقه

یکی از نخستین دغدغه‌های یک توسعه‌دهنده خوب وب نوشتن کد تمیز و جلوگیری از تکرار کد است. این راهبرد در زمان توسعه اپلیکیشن‌های بزرگ و مقیاس‌پذیر که ممکن است در آینده با معرفی قابلیت‌های جدید گسترش یابند، ضرورتی دو چندان می‌یابد. در این مقاله با روش ساخت یک کامپوننت دکمه با قابلیت استفاده مجدد در انگولار آشنا می‌شویم.

کامپوننت‌های با قابلیت استفاده مجدد بسیار مهم هستند و تفاوت بین یک پروژه موفق و پروژه با بدهی فنی بالا را تعیین می‌کنند. کامپوننت دکمه‌ای که در این مقاله می‌سازیم، می‌تواند بر اساس پیکربندی ارائه شده، یک دکمه متنی یا تصویری را نمایش دهد.

گام 1: ساختار پایه

قبل از هر چیز باید بگوییم که وقتی در مورد ساختار یک کامپوننت با قابلیت استفاده مجدد تأمل می‌کنیم، باید همه کاربردهایی که می‌تواند داشته باشد را در نظر داشته باشیم. در مورد یک دکمه با قابلیت استفاده مجدد، باید یک کامپوننت ارائه‌ای (یا dumb) بسازیم که پیکربندی صحیح را از کامپوننت والد خود می‌گیرد.

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

@Component({
  selector: 'app-button',
  templateUrl: './button.component.html',
  styleUrls: ['./button.component.scss']
})
export class ButtonComponent implements OnInit {
  @Input() buttonConfig: any;
  constructor() {}

  ngOnInit() {}
}

شیء buttonConfig استایل‌بندی و اطلاعاتی اضافی در مورد نوع دکمه‌ای که می‌خواهیم رندر کنیم، ارائه می‌کند. اگر بخواهیم یک دکمه متنی داشته باشیم، buttonConfig شامل یک مشخصه text خواهد بود و در غیر این صورت اگر بخواهیم یک دکمه تصویری داشته باشیم، در پیکربندی یک منبع تصویر معرفی می‌کند.

کد HTML شامل دو قالب متفاوت خواهد بود که یکی برای دکمه متنی و دیگری برای دکمه تصویری است. با استفاده از الگوی ngTemplateOutlet می‌توانیم تعیین کنیم که چه زمانی هر کدام از آن‌ها باید رندر شوند. در این مورد اگر پیکربندی شامل مشخصه text باشد، قالب ‎#text رندر می‌شود و در صورت عدم وجود مشخصه text قالب ‎#image رندر خواهد شد.

  
<ng-container *ngTemplateOutlet="buttonConfig['text'] ? text : image">
</ng-container>

<!-- Text Button -->
<ng-template #text>

</ng-template>

<!-- Image Button -->
<ng-template #image>

</ng-template

گام 2: مارکاپ دکمه‌ها

اکنون که قالب‌ها آماده هستند، می‌توانیم آن‌ها را با کد دکمه‌ها پر کنیم. چنان که در کد زیر می‌بینید، دکمه متنی مشخصه buttonConfig.text را از طریق میان‌یابی نشان می‌دهد. دکمه تصویری صرفاً یک تصویر قالب کلیک نمایش می‌دهد که دارای مشخصه buttonConfig.src به عنوان منبع تصویر است.

<ng-container *ngTemplateOutlet="buttonConfig['text'] ? text : image">
</ng-container>

<!-- Text Button -->
<ng-template #text>
  <button type="button"
          [ngStyle]="buttonConfig.styles"
          (click)="onTextBtnClick()">
    {{ buttonConfig.text | uppercase}}
  </button>
</ng-template>

<!-- Image Button -->
<ng-template #image>
  <img alt="image button"
       [src]="buttonConfig.src"
       [ngStyle]="buttonConfig.styles"
       (click)="onImgBtnClick()">
</ng-template>

گام 3: پیکربندی

اکنون که کامپوننت دکمه آماده دریافت پیکربندی‌اش به عنوان ورودی است، می‌توانیم استایل‌های سفارشی را در کامپوننت والد تعریف کنیم. در این مورد می‌خواهیم یک شیء textBtnConfig و یک شیء imgBtnConfig ایجاد کنیم که شیوه استفاده از کامپوننت دکمه برای رندر کردن دو وهله متفاوت را به صورت همزمان با پیکربندی‌های مختلف نمایش می‌دهد.

باید توجه داشته باشید که چون ما استایل‌بندی CSS را در یک شیء تایپ اسکریپت اعلان می‌کنیم، باید از قالب camelCase در مورد نامگذاری مشخصه‌ها استفاده کنیم. از این رو ‘background-color’ به صورت ‘backgroundColor’ در می‌آید و در موارد دیگر هم به این شیوه عمل می‌کنیم.

import { Component } from '@angular/core';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.scss']
})
export class AppComponent {
  message = 'Click on a button';
  textBtnConfig = {
    styles: {
      position: 'relative',
      width: '150px',
      height: '60px',
      backgroundColor: '#f92672',
      color: '#fff',
      fontFamily: 'sans-serif',
      fontSize: '20px',
      borderRadius: '10px',
      marginTop: '30px'
    },
    text: 'Click Here'
  };

  imgBtnConfig = {
    styles: {
      position: 'relative',
      width: '100px',
      height: '100px'
    },
    src: './assets/conversation.png'
  };

  onClickEventReceived(event: string) {
    this.message = event;
  }
}

گام 4: رندر کردن

در نهایت می‌توانیم کامپوننت دکمه را برای وهله‌سازی دو دکمه در کامپوننت والد مورد استفاده قرار دهیم:

<section>
  <h1>DIFFERENT BUTTONS, SAME COMPONENT!</h1>
  <span>{{message}}</span>
  <div class="btns-container">
    <app-button [buttonConfig]="textBtnConfig"
                (textBtnClickEmt)="onClickEventReceived($event)"></app-button>
    <app-button [buttonConfig]="imgBtnConfig"
                (imgBtnClickEmt)="onClickEventReceived($event)"></app-button>
  </div>
  <div class="copyright">
    <span>Code by Alessia Amitrano.</span>
    <span>
      Icons made by <a href="https://www.flaticon.com/authors/freepik"
         title="Freepik">Freepik</a> from <a href="https://www.flaticon.com/"
         title="Flaticon">www.flaticon.com</a></span>
  </div>
</section>

زمانی که اپلیکیشن عرضه شد، نتیجه مانند تصویر زیر خواهد بود:

کامپوننت دکمه با قابلیت استفاده مجدد در انگولار

سخن پایانی

در این راهنما با شیوه ساخت یک کامپوننت با قابلیت استفاده مجدد در انگولار آشنا شدیم که می‌توان در موقعیت‌های متفاوتی از آن استفاده کرد. بدیهی است که این یک حالت ساده شده است، اما رویکردی را نشان می‌دهد که توسعه‌دهندگان می‌توانند برای هر چالشی از این دست مورد استفاده قرار دهند.

فکر کنید بدون استفاده از کامپوننت‌های با قابلیت استفاده مجدد مجبور هستیم چه مقدار کد تکراری بنویسیم. به علاوه کامپوننت‌های با قابلیت استفاده مجدد، امکان پیاده‌سازی قابلیت‌های جدید را برای هر وهله از کامپوننت با کمترین مقدار تغییرات کد فراهم می‌سازند. بدین ترتیب اگر بخواهیم متد جدیدی اضافه کنیم، مهم نیست که دکمه ما به صورت متنی یا تصویری است و در مورد هر نوع دکمه‌ای امکان انجام این کار وجود دارد. همه کدهای ارائه شده در این مقاله را می‌توانید در این ریپوی گیت‌هاب (+) ملاحظه کنید.

اگر این مطلب برای شما مفید بوده است، آموزش‌های زیر نیز به شما پیشنهاد می‌شوند:

==

بر اساس رای ۱ نفر
آیا این مطلب برای شما مفید بود؟
شما قبلا رای داده‌اید!
اگر بازخوردی درباره این مطلب دارید یا پرسشی دارید که بدون پاسخ مانده است، آن را از طریق بخش نظرات مطرح کنید.
منابع:
better-programming

نظر شما چیست؟

نشانی ایمیل شما منتشر نخواهد شد. بخش‌های موردنیاز علامت‌گذاری شده‌اند *