معرفی Databinding (ارتباطات داده‌ای) در انگولار

18 تیر 1396
angular-two-way-databinding

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

Databinding یا ارتباطات داده در انگولار چیست؟

در انگولار مفهومی تحت عنوان databing مطرح شد که به معنی ارتباطات داده‌ای بین قسمت منطق یا کنترلر برنامه که به زبان تایپ اسکریپت نوشته می‌شود با قسمت نمایشی برنامه که به زبان Html نوشته شده است.

به عبارت دیگر databinding به معنی ارتباط app.component.ts با app.component.html است. برای تفهیم بیشتر به تصویر زیر دقت کنید:

دیاگرام ارتباطات داده‌ای یا Databinding در انگولار

همانطور که در تصویر ملاحظه می‌کنید ابتدا داده توسط سمت منطقی و کنترلی برنامه پردازش شده و سپس داده‌ی محاسبه شده به قالب html ارسال می‌شود (اولین راه ارتباطی)

در این بین، ارسال داده به دو صورت امکان‌پذیر است:

روش ۱) ارسال داده به صورت رشته‌ای به قالب HTML:

{{ data }}


روش ۲) ارسال داده به ویژگی (property) که در ادامه درباره آن صحبت خواهیم کرد:

[property] = "data"


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

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

(event) = "expression"

که در این حالت expression همان رفتاریست که به کاربر ارائه خواهیم داد. این رفتار می‌تواند یک متد، تابع و یا یک پیام باشد.

two-way Databinding چیست؟

در بسیاری از مقالات عبارت two-way Databinding به گوش شما خورده است و شاید برای شما کمی گنگ باشد اما اینجا به این سوال شما پاسخ داده‌ایم و به این تعامل ارتباطات داده‌ای در اصطلاح برنامه‌نویسی two-way databinding گفته می‌شود.

حال اگر دو مسیر ارتباطات داده‌ای را با یکدیگر ترکیب کنیم متوجه خواهید شد که یک روش واحد برای ارسال داده و انتظار برای دریافت پاسخ وجود دارد که به آن ngModel گفته می‌شود.

ngModel وظیفه‌ی حمل اطلاعات را به عهده دارید و به صورت زیر تعریف می‌شود:

[(ngModel)] = "data"

حال در ادامه به تشریح هر قسمت می‌پردازیم.

ارسال رشته‌ای داده یا String Interpolation در ارتباطات داده ای

داده‌ها را می‌توان در سمت منطق و کنترل برنامه که در فایلهای با پسوند ts. محاسبه می‌شوند، به خروجی HTML ارسال کرد. برای اینکار از دو علامت {{ }} استفاده کرده و در نهایت متغییری که حاوی اطلاعات است را درون آن قرار می‌دهیم.

مثال فصول گذشته را ادامه می‌دهیم. می‌خواهیم در قسمت خروجی صفحه HTML یک id و status (وضعیت) برای سرور خود مشخص کنیم.

بنابراین در فایل server.component.html و درون کلاس ServerComponent ابتدا متغییری که می‌خواهیم یک مقدار را به آن اختصاص یا پردازشی روی آن انجام دهیم را معرفی می‌کنیم:

import {Component} from "@angular/core"

@Component({
    selector: 'app-server',
    templateUrl: "./server.component.html"
})

export class ServerComponent {
    serverId: number = 10;
    serverStatus: string = 'خاموش';
}

در قسمت کلاس کامپوننت ServerComponent دو متغییر به نام‌های serverId و serverStatus تعریف کرده‌ایم.

برای یادآوری خدمت شما عزیزان اطلاع می‌دهم که زبان تایپ اسکریپت یک زبان Strongly Typed هست. یعنی انواع تمام متغییرها درون آن مشخص می‌شود تا خوانایی کدها بهبود پیدا کند.

بنابراین پس از تعریف نام متغییر باید یک علامت : قرار داده و نوع داده را مشخص کنیم و در نهایت با انتساب (علامت =) مقدار موردنظر را به آن اختصاص دهیم.

پس serverId از نوع عددی (number) و serverStatus از نوع رشته‌ای (string) می‌باشد.

حال به فایل server.component.html رفته تا داده‌های ارسالی به HTML را برای کاربر نمایش دهیم. این مسیر رفت ارسال داده است. بنابراین در این فایل داریم:

<p>وضعیت {{'سرور'}} با ID: {{serverId}} برابر است با: {{serverStatus}}</p>

اگر به این کد توجه کنید مقادیر serverId و serverStatus به صورت خودکار به قالب HTML ارسال می‌شوند. در واقع تمام انواع داده‌ای به صورت توکار در زبان تایپ اسکریپت به حالت String تبدیل (cast) شده و جهت نمایش در خروجی مورد استفاده قرار می‌گیرند.

شاید این سوال برای شما پیش آمده است که چرا عبارت سرور را درون دو علامت ' ' قرار داده‌ایم. با اینکار می‌خواستیم به شما عزیزان اطلاع دهیم که اگر داخل علامت‌های {{ }} یک عبارت رشته‌ای نوشته شود، عینا نمایش داده خواهد شد. در واقع علامت {{ }} وظیفه‌ی چاپ و نمایش اطلاعات را دارد.

بنابراین خروجی ما در این حالت به صورت زیر  خواهد بود:

خروجی اضافه کردن یک string interpolation

همچنین می‌توان یک با تعریف یک متد (تابع) خروجی را نمایش دهیم که در این حالت فایل server.component.ts را به صورت زیر ویرایش خواهیم کرد:

import {Component} from "@angular/core"

@Component({
    selector: 'app-server',
    templateUrl: "./server.component.html"
})

export class ServerComponent {
    serverId: number = 10;
    serverStatus: string = "خاموش";

    getServerStatus(){
        return this.serverStatus;
    }
}

حال فایل مربوط به قالب server.component.html را نیز ویرایش می‌کنیم:

<p>وضعیت {{'سرور'}} با ID: {{serverId}} برابر است با: {{getServerStatus()}}</p>

در این حالت ما بجای استفاده از یک متغییر، متدی را تعریف و سپس آن را به قالب HTML اتصال (Bind) کردیم. خروجی این مثال با حالت قبل دقیقا برابر است.

ارسال داده به صورت Property

همانطور در بالا اشاره کردیم یکی دیگر از روش‌های ارسال داده به صورت Property است که در این روش داده در بستر یک متغییر مشخص ارسال می‌شود.

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

در این حالت قالب فایل servers.component.html را باز کرده و به صورت زیر ویرایش می‌کنیم:

<button class="btn btn-primary">سرور جدید</button>

<app-server></app-server>
<app-server></app-server>

همچنین توجه داشته باشید که برای مشاهده تغییرات باید فایل servers.comopnent.html را درون فایل کنترلر کامپوننت که به مسیر servers.component.ts است به صورت زیر ویرایش کنید:

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

@Component({
  selector: 'app-servers',
  templateUrl: './servers.component.html',
  styleUrls: ['./servers.component.css']
})
export class ServersComponent implements OnInit {

  constructor() { }

  ngOnInit() {
  }

}

در صورتیکه این کار را موفقیت انجام داده باشید با خروجی زیر روبه‌رو خواهید شد:

خروجی اضافه کردن یک دکمه به همراه property به قالب HTML

حال برای کنترل بیشتر روی این دکمه یک سری تمهیدات را در نظر میگیریم. در حالت عادی دکمه را به صورت خاموش (disable) تنظیم می‌کنیم. بنابراین کد HTML ما به صورت زیر تغییر می‌کند:

<button class="btn btn-primary" disabled>سرور جدید</button>

<app-server></app-server>
<app-server></app-server>

یعنی می‌خواهیم دکمه ابتدا غیرفعال باشد و پس از مدت زمانی خاصی فعال شود.

بنابراین باید یک متغییر به نام allowNewServer از نوع boolean با مقدار false درون کنترلر servers.component.ts تعریف می‌کنیم تا مقدار اولیه این دکمه false (غیرفعال) باشد و سپس درون constructor (سازنده پیشفرضی که به محض فراخوانی کلاس به صورت خودکار اجرا می‌شود)  با استفاده از تابع جاوا اسکریپت setTimeout مدت زمان را برای فعال‌سازی مشخص کنیم بنابراین داریم:

import { Component, OnInit } from '@angular/core';
import {createServer} from "http";

@Component({
  selector: 'app-servers',
  templateUrl: './servers.component.html',
  styleUrls: ['./servers.component.css']
})
export class ServersComponent implements OnInit {

  allowNewServer: boolean = false;
  
  constructor() { 
    setTimeout(()=>{
        this.allowNewServer = true;
    }, 2000);
  }

  ngOnInit() {
  }

}

پس از گذشت ۲۰۰۰ میلی‌ثانیه مقدار متغییر allowNewServer را به ture تبدیل کرده‌ایم اما نکته‌ی قابل توجه اینجاست که پس از ذخیره کردن این فایل دکمه همچنان در صفحه مرورگر شما خاموش است. خب خیلی منطقی‌ست!

شما متد را درون سازنده تعریف کرده‌اید و اجرا می‌شود ولی هیچ ارتباطی با خروجی HTML ندارد. بنابراین در اینجا از روش اتصال اطلاعات (Binding) به ویژگی‌ها (properties) استفاده می‌کنیم.

یعنی می‌خواهیم یک ویژگی خام HTML را (در اینجا property ما disabled است) به صورت داینامیک مورد استفاده قرار دهیم. یعنی بر اساس یک سری شرایط و دستورات این ویژگی‌ها به کد HTML ما اضافه و یا از آنها حذف شوند.

بنابراین برای داینامیک کردن ویژگی‌های خام HTML از علامت [ ] براکت استفاده خواهیم کرد. پس فایل servers.component.html را به صورت زیر ویرایش می‌کنیم:

<button class="btn btn-primary" [disabled]="!allowNewServer">سرور جدید</button>

<app-server></app-server>
<app-server></app-server>

همانطور که ملاحظه می‌کنید در واقع به ویژگی disable خاصیت پویا و داینامیک بودن را داده‌ایم یعنی در ابتدا دکمه خاموش (disable = true) است و سپس دکمه روشن (disable = false) می‌شود.

بسیار عالی به شما عزیزان تبریک می‌گوییم. تا به اینجای کار با مسیر یک طرفه ارسال داده از طرف منطق و کنترلر برنامه به خروجی HTML (کاربر) آشنا شدید. در جلسه بعدی با نحوه‌ی ارسال درخواست کاربر و دریافت پاسخ (رویدادها و eventها) آشنا خواهید شد. با ما همراه باشید.

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

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

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

دیدگاه‌های شما (2 دیدگاه)

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

علی ظریف
21 بهمن 1398
در عبارت زیر عملیات باید در مسیر servers.component.ts انجام شود.به اشتباه مسیر server.component.html معرفی شده: "بنابراین در فایل server.component.html و درون کلاس ServerComponent ابتدا متغییری که می‌خواهیم یک مقدار را به آن اختصاص یا پردازشی روی آن انجام دهیم را معرفی می‌کنیم:"

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

saeed
09 آذر 1397
با سلام و خسته نباشید... من دارم آموزش هاتون رو دنبال میکنم و فقط میتونم بگم تا اینجای کار عالی بود

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