ارسال اطلاعات به ویژگی‌ها (Property) و پاسخ به رویدادها (Event) در دستورهای صفتی

16 آبان 1397
angular-property-and-events-directives

در فصل گذشته شما را با نحوه‌ی تعریف یک دستور صفتی در انگولار آشنا کردیم. همچنین جهت استاندارد سازی از کلاسی تحت عنوان Renderer2 بهره بردیم. حال در این فصل قصد داریم مفاهیم مربوط به پاسخ به یک رویداد (Event) درون دستورات صفتی و ارسال اطلاعات (Bind) به ویژگی‌ها (Property) موجود در این دستورات بپردازیم تا به صورت تخصصی‌تر بتوانید از دستورات صفتی استفاده نمایید.

پاسخ به یک رویداد (Event) در انگولار

در جلسه‌ی گذشته مثالی را تحت بررسی قرار دادیم که طی آن یک دستور صفتی ایجاد کردیم و در نهایت آن را در صفحه نمایش مشاهده فرمودید. حال در این بخش می‌خواهیم هنگامیکه کاربر روی یک تگ خاص قرار گرفت به عنوان مثال رنگ پس زمینه‌ی آن تغییر کند و یا وقتی ماوس خود را از روی آن تگ برداشت رنگ آن مجددا به حالت اولیه باز گردد.

این موضوع دقیقا مشابه رخ دادن یک رویداد یا event است. یعنی شما در ابتدا یک event تعریف می‌کنید که متناسب با آن دستور خاص عمل خواهد کرد.

معرفی مفسر HostListener@ در انگولار

برای تعریف یک event درون یک دستور دلخواه، باید از مفسر یا دکوراتور HostListener استفاده کرده و نام event را به صورت آرگومان به آن ارسال کنی. در نهایت نام رویدادی که در DOM رخ می‌دهد را به ادامه‌ی دستور خود بیافزاییم.

برای روشن‌تر شدن درک این موضوع مثال قبل را در نظر بگیرید. بنابراین فایل appBetterHighlight.directive.ts را باز کرده و دستورهای زیر را به آن اضافه می‌کنیم:

import {Directive, ElementRef, HostListener, OnInit, Renderer2} from '@angular/core';

@Directive({
  selector: '[appBetterHighlight]'
})
export class BetterHighlightDirective implements OnInit {

  constructor(private elRef: ElementRef, private renderer: Renderer2) {
  }

  ngOnInit() {

  }

  @HostListener('mouseenter') mouseover(eventData: Event) {
    this.renderer.setStyle(this.elRef.nativeElement, 'background-color', 'orange')
  }

  @HostListener('mouseleave') mouseleave(eventData: Event) {
    this.renderer.setStyle(this.elRef.nativeElement, 'background-color', 'transparent')
  }
}

بسیار عالی! کافیست این کد را اجرا کنید. همانطور که ملاحظه می‌کنید با قرار دادن ماوس روی تگ موردنظر با خروجی زیر مواجه خواهید شد

خروجی پس از پاسخ به یک رویداد

و در حالت عادی اگر ماوس خود را از روی تگ بردارد تصویر زیر برای شما نمایش داده می‌شود:

خروجی پس از پاسخ به یک رویداد

معرفی مفسر HostBinding@ در انگولار

قبل از توضیح این مفسر باید خدمت شما عزیزان عرض کنم که استفاده از دستور renderer به عنوان اصولی‌ترین راه شناخته می‌شود اما گاهی می‌خواهیم یک ویژگی را با تعداد خط کمتری تغییر دهیم. در این صورت می‌توان از مفسر HostBinding استفاده کرد که یک ویژگی را روی یک صفت CSS پیاده‌سازی می‌کند.

برای درک بهتر مثال قبل را در نظر بگیرید. برای آنکه رنگ پس زمینه در تگی که از دستور appBetterHighlight پیروی می‌کند، تغییر یابد می‌توان از این مفسر بهره به صورت زیر بهره برد:

import {Directive, ElementRef, HostBinding, HostListener, OnInit, Renderer2} from '@angular/core';

@Directive({
  selector: '[appBetterHighlight]'
})
export class BetterHighlightDirective implements OnInit {

  @HostBinding('style.backgroundColor') backgroundColor: string = 'transparent';
  
  constructor(private elRef: ElementRef, private renderer: Renderer2) {
  }

  ngOnInit() {

  }

  @HostListener('mouseenter') mouseover(eventData: Event) {
    // this.renderer.setStyle(this.elRef.nativeElement, 'background-color', 'orange')
    this.backgroundColor = 'orange'
  }

  @HostListener('mouseleave') mouseleave(eventData: Event) {
    // this.renderer.setStyle(this.elRef.nativeElement, 'background-color', 'transparent')
    this.backgroundColor = 'transparent'
  }
}

همانطور که ملاحظه کردید یک ویژگی به نام backgroundColor در ابتدا تعریف کردیم و مقدار style.backgroundColor را معادل آن قرار داده و توسط HostBinding آن را اعمال می‌کنیم.

بنابراین درون رویدادهای mouseover و mouseleave نیز این تغییرات را با دسترسی به این ویژگی و انتساب یک مقدار مشخص به آنها، ایجاد می‌کنیم. خروجی این روش نیز دقیقا مشابه روش استفاده از کلاس Renderer2 است.

ارسال (Bind) اطلاعات به یک ویژگی (Property) در انگولار

فرض کنید می‌خواهیم اطلاعات را سمت کامپوننت پردازش کرده و سپس به یک تگ به عنوانه ویژگی ارسال (Bind) کنیم. در این حالت باید مشابه قبل یک ویژگی دریافت شده با مفسر Input@ ایجاد کرده و سپس مقادیر موجود در فایل دستورات (directive.ts) را متناسب با آن تنظیم کنیم.

بنابراین در فایل better-highlight.directive.ts مثال قبل تغییرات زیر را لحاظ خواهیم کرد:

import {Directive, ElementRef, HostBinding, HostListener, Input, OnInit, Renderer2} from '@angular/core';

@Directive({
    selector: '[appBetterHighlight]'
})
export class BetterHighlightDirective implements OnInit {

    @Input() defaultColor: string;
    @Input() highlightColor: string;

    @HostBinding('style.backgroundColor') backgroundColor: string = this.defaultColor;

    constructor(private elRef: ElementRef, private renderer: Renderer2) {
    }

    ngOnInit() {

    }

    @HostListener('mouseenter') mouseover(eventData: Event) {
        // this.renderer.setStyle(this.elRef.nativeElement, 'background-color', 'orange')
        this.backgroundColor = this.highlightColor;
    }

    @HostListener('mouseleave') mouseleave(eventData: Event) {
        // this.renderer.setStyle(this.elRef.nativeElement, 'background-color', 'transparent')
        this.backgroundColor = this.defaultColor;
    }
}

و در نهایت امر داخل فایل app.component.ts که این دستور را اضافه کرده‌ایم، ویژگی را bind (ارسال) می‌کنیم:

<div class="container" dir="rtl" style="margin-top: 30px;">
    <div class="row">
        <div class="col-xs-12">
            <button class="btn btn-primary" (click)="onlyFalse = !onlyFalse">نمایش اعداد فرد</button>
        </div>
        <br><br>
        <ul class="list-group">
            <div *ngIf="onlyFalse">
                <li class="list-group-item"
                    *ngFor="let odd of oddNumber"
                    [ngClass]="{odd: odd % 2 !== 0}"
                    [ngStyle]="{backgroundColor: odd % 2 !== 0 ? 'Yellow':'transparent'}"
                >
                    {{odd}}
                </li>
            </div>
            <div *ngIf="!onlyFalse">
                <li class="list-group-item"
                    *ngFor="let even of evenNumber"
                    [ngClass]="{even: even % 2 === 0}"
                    [ngStyle]="{backgroundColor: odd % 2 !== 0 ? 'Black':'transparent'}"
                >
                    {{even}}
                </li>
            </div>
            <li class="list-group-item" appBasicHighlight>این تگ تحت تاثیر دستور appBasicHighlight قرار گرفته است. روکسو</li>
            <li class="list-group-item" appBetterHighlight [defaultColor]="'pink'" [highlightColor]="'brown'">این تگ تحت تاثیر دستور appBetterHighlight قرار گرفته است. روکسو</li>
        </ul>
    </div>
</div>

همانگونه که مشاهده خواهید کرد ویژگی defaultColor را برابر رنگ صورتی و ویژگی highlightColor را معادل رنگ قهوه‌ای قرار داده‌ایم. بنابراین خروجی ما در حالتی که صفحه بروز می‌شود به صورت زیر است:

خروجی پس از ارسال یک ویژگی

و هنگامیکه روی تگ موردنظر بیاستیم خروجی ما معادل تصویر زیر می‌باشد:

خروجی پس از ارسال یک ویژگی

بسیار عالی به شما عزیزان مجددا تبریک می‌گوییم در این بخش توانستید مهارتهای خود را جهت ایجاد تغییرات به هنگام ساخت یک دستور، افزایش دهید. همچنین با نحوه‌ی ارسال اطلاعات به یک ویژگی (Property) یا پاسخ به یک رویداد (Event) آشنا شدید. در فصل بعدی به آموزش نحوه‌ی کار با دستورهای ساختاری (Structural Directive) می‌پردازیم. با ما همراه باشید.

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

دوره آموزش انگولار به زبان فارسی + پروژه ساخت فروشگاه اینترنتی

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

در این قسمت، به پرسش‌های تخصصی شما درباره‌ی محتوای مقاله پاسخ داده نمی‌شود. سوالات خود را اینجا بپرسید.