ایجاد دستورهای ساختاری (Structural Directive) در انگولار

16 آبان 1397
angular-structural-directive

در این فصل با آموزش نحوه‌ی تولید دستورهای ساختاری (Structural Directive) در خدمت شما عزیزان هستیم. مطالعه‌ی این بخش لازمه‌ی ورود به دنیای حرفه‌ی ساخت دستورهای متنوع است. با ما همراه باشید.

مقدمه

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

دستور ساختاری (Structural Directive): به دستوری گفته می‌شود که روی المان‌های DOM تاثیر مستقیم گذاشته و یک تگ را حذف یا اضافه می‌کند.

بنابراین با شروع یک مثال ادامه‌ی روند آموزشی را در پی می‌گیریم.

شروع با یک مثال

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

بنابراین ابتدا در خط فرمان Angular CLI دستور زیر را تایپ می‌کنیم تا یک پوشه به همراه فایل unless.directive.ts برای ما تولید شود:

ng g d unless/unless

سپس فایل unless.directive.ts را باز کرده و عبارت‌های زیر را درون آن قرار می‌دهیم:

import {Directive, Input, TemplateRef, ViewContainerRef} from '@angular/core';

@Directive({
    selector: '[appUnless]'
})
export class UnlessDirective {

    @Input() set appUnless(condition: boolean){
        if(!condition){
            this.vcRef.createEmbeddedView(this.templateRef)
        }else{
            this.vcRef.clear();
        }
    }
    constructor(private templateRef: TemplateRef<any>, private vcRef: ViewContainerRef) {
    }

}

همانطور که ملاحظه می‌کنید ابتدا یک ویژگی به نام appUnless تعریف کرده‌ایم که مقدار موردنظر condition را به عنوان ورودی از قالب HTML دریافت می‌کند سپس داخل این ویژگی یک سری دستورهای شرطی قرار داده‌ایم. اما قبل از اینکه دستورات شرطی را بررسی کنیم به توضیح ویژگی‌های templateRef و vcRef می‌پردازیم.

ویژگی templateRef دقیقا مشابه elementRef است با این تفاوت که elementRef روی تگ‌ها یا المان‌ها اعمال می‌شود ولی templateRef روی یک دسته از تگ‌ها که تشکیل template می‌دهند اعمال خواهد شد.

همچنین ویژگی vcRef از نوع کلاس ViewContainerRef تعریف شده است که بیانگر مفهوم «کجایی» یا "where" یک دستور ساختاری می‌باشد. به عبارت دیگر templateRef مفهوم چطور و ViewContainerRef مفهوم کجایی را می‌رساند.

همچنین ویژگی appUnless را به صورت set تعریف کرده‌ایم که تنها مقادیر را بپذیرد و معادل قرار دهد و نتوان از روی آن مقداری را خواند.

حال با این تغییرات درون فایل app.component.html نیز باید دستورهایی مشابه ذیل قرار دهیم:

<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'}"-->
                <!--&gt;-->
                    <!--{{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'}"-->
                <!--&gt;-->
                    <!--{{even}}-->
                <!--</li>-->
            <!--</div>-->
            <div *appUnless="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>

<!--<div class="container" dir="rtl">-->
<!--<div class="row">-->
<!--<div class="col-xs-12">-->
<!--<app-lifecycle></app-lifecycle>-->
<!--</div>-->
<!--</div>-->
<!--</div>-->


<!--<div class="container" dir="rtl">-->
<!--<div class="row">-->
<!--<div class="col-xs-12">-->
<!--<app-servers></app-servers>-->
<!--</div>-->
<!--</div>-->
<!--</div>-->

در این مجموعه‌ی کد یک سری کدها را به صورت کامنت قرار داده‌ایم که دقیقا در جریان تغییرات باشید.

بنابراین در این بخش یک دستور ایجاد کردیم که شرط درون آن به صورت خلاف شرط معمولی if تعریف شده است.

دستور ساختاری ng-switch در انگولار

در صورتیکه با یکی از زبان‌های برنامه‌نویسی سطح بالا کار کرده باشید همگی با مفهوم دستور شرطی switch آشنا هستید. این دستور متناسب با مقداری که به عنوان value دریافت می‌کند یکی از شروط را اجرا خواهد کرد و در صورتیکه هیچ یک از caseهای آن با شرط موردنظر همسان نباشد یا از شرط خارج شده و یا یک مقدار پیش‌فرض (default) را ارائه می‌دهد.

برای درک بهتر این دستور در انگولار یک مثال خدمت شما عزیزان ارائه خواهیم داد. بنابراین فایل app.component.ts را باز می‌کنیم و دستور زیر را درون آن قرار می‌دهیم که شامل یک ویژگی به نام value است تا به عنوان مقادیر و شروط به دستور switch ارسال شود:

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

@Component({
    selector: 'app-root',
    templateUrl: './app.component.html',
    styleUrls: ['./app.component.css']
})
export class AppComponent {

    value: number = 10;

    onLoadOdd() {

    }
}

همانطور که ملاحظه می‌کنید یک ویژگی به نام value تعریف کرده و سپس مقدار معادل آن را برابر ۱۰ قرار داده‌ایم. حال باید دستور ساختاری ngswitch را اعمال کنیم. بنابراین فایل app.component.ts را باز کرده و سپس:

<div class="col-xs-12" [ngSwitch]="value">
     <p *ngSwitchCase="10"> مقدار برابر ۱۰ می باشد</p>
     <p *ngSwitchCase="15"> مقدار برابر ۱۵ می باشد</p>
     <p *ngSwitchCase="100"> مقدار برابر ۱۰۰ می باشد</p>
     <p *ngSwitchDefault> مقدار برابر حالت پیشفرض می باشد</p>
</div>

با بررسی مجموعه دستور بالا باید حدس زده باشید که فرآیند اجرا به چه صورت است. در ابتدا یک ویژگی به نام value به ویژگی توکار ngSwitch اعمال می‌شود (Binding) سپس متناسب با مقادیری که از کنترلر کامپوننت app.component.ts دریافت می‌کند تصمیم گیری خود را در دستورهای ستاره‌دار ngSwitchCase* انجام می‌دهد. در صورتیکه مقدار value برابر هیچ یک از مقادیر فوق آنگاه تگ با دستور ngSwitchDefault* اجرا می‌شود.

بسیار عالی به شما عزیزان تبریک می‌گوییم. خوشبختانه با موفقیت این فصل را به اتمام رساندیم و تمام مباحث مربوط به دستورهای ساختاری و صفتی انگولار را بررسی کردیم. امیدواریم این مجموعه مورد پسند شما واقع شده باشد. در فصل بعدی به صورت مفصل و عمیق در ارتباط با مفاهیمی چون تزریق وابستگی (Dependency Injection) و سرویس‌ها (Services) در انگولار صحبت خواهیم کرد. با ما همراه باشید.

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

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

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

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