آموزش انتقال داده بین کامپوننت ها در انگولار

چگونه در AngularJS بین کامپوننت ها داده را انتقال دهیم؟ هنگام نوشتن برنامه های انگولار حتما برای شما هم پیش امده که بخواید بین کامپوننت ها داده ها را انتقال دهید. برای انتقال داده ها به طور کلی چندین روش وجود دارد که ان هارا مورد برسی قرار میدهیم

دوره های شبکه، برنامه نویسی، مجازی سازی، امنیت، نفوذ و ... با برترین های ایران
Parent to Child: Sharing Data via Input

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

#parent.component.ts

import { Component } from '@angular/core';
@Component({
  selector: 'app-parent',
  template: `
    <app-child [childMessage]="parentMessage"></app-child>
  `,
  styleUrls: ['./parent.component.css']
})
export class ParentComponent{
  parentMessage = "message from parent"
  constructor() { }
}

کلاس فرزند هم به صورت زیر اضافه میکنیم

#child.component.ts

import { Component, Input } from '@angular/core';
@Component({
  selector: 'app-child',
  template: `
      Say {{message}}
  `,
  styleUrls: ['./child.component.css']
})
export class ChildComponent {
  @Input() childMessage: string;
  constructor() { }
}

اگر دقت کنید ما در کامپوننت پدر امدیم و یک تگ از کامپوننت فرزند ساختیم در اینجا هم مشخص میشود کدام کاموننت پدر و کدام یک فرزند است

  • نکته ! به طور کلی وقتی Selector یک کاموننت در کاموننت دیگری نوشته میشود ُ ان کامپوننت فرزند و کامپوننتی که سلکتور در ان قرار دارد پدر میباشد.

همانطور که ملاحظه میفرمیاد درون کامپوننت پدر یک تگ از کاموننت فرزند قرار داده ایم و دایرکتیو childMessage را نوشته(میتواند هر اسمی باشد)‌و مقدار parentMessage را که در .ts مقدار parentMessage = "message from parent انتصاب داده شده است را قرار داده ایم. حال سراغ کامپونت فرزند رفته و ان را توضیح میدهیم ؛ داخل فایل ts کامپوننت فرزند یک مفسر به نام Input تعرف کرده ایم که کاران وارد کردن داده میباشد

 @Input() childMessage: string;

نام ان را هم نام با دایرکتیو کامپوننت پدر قرار میدهیم ؛ حال اگر برنامه را اجرا کنید به درستی خروجی ان را خواهید دید و درون کامپوننت فرزند عبارتmessage from parent نمایان خواهد شد

Child to Parent: Sharing Data via ViewChild

حال فرض کنید میخاهید عکس قصیه بالا یعنی از کامپ.ننت فرزند به پدر داده ارسال کنید

#parent.component.ts

import { Component, ViewChild, AfterViewInit } from '@angular/core';
import { ChildComponent } from "../child/child.component";
@Component({
  selector: 'app-parent',
  template: `
    Message: {{message}}
    <app-child></app-child>
  `,
  styleUrls: ['./parent.component.css']
})
export class ParentComponent implements AfterViewInit {
  @ViewChild(ChildComponent) child;
  constructor() { }
  message:string;
  ngAfterViewInit() {
    this.message = this.child.message
  }
}

تنها تغیری که مشاهده میکنید نوشتن دستور

  @ViewChild(ChildComponent) child;

و سپس نمایش ان با دستور

 this.message = this.child.message

متغیر message را درون کامپوننت فرزند تعریف خواهیم کرد در ادامه بیشتر توضیح خواهم داد . دقت کنید برای نمایش باید ان را در هوک ngAfterViewInit قرار دهید برای این کار باید کلاس از اینترفیس AfterViewInit ارث بری شود و همچنین طبق معمول باید یک تگ از کامپوننت فرزند در کامپننت پدر قرار دهیم ، حال سراغ کامپوننت فرزند میرویم و کد زیر را در ان قرار میدیم

#child.component.ts

import { Component} from '@angular/core';
@Component({
  selector: 'app-child',
  template: `
  `,
  styleUrls: ['./child.component.css']
})
export class ChildComponent {
  message: string = "Hola Mundo!"
  constructor() { }
}

همانطور ملاحظه میکنید درون کامپوننت فرزند هیچ کار خاصی انجام ندادیم فقط یک متغیر ساده تعریف کردیم ، اگر خاطرتان باشد هنگام فراخوانی در کامپوننت پدر به طور مستقیم از این متغیر استفاده کردیم

Child to Parent: Sharing Data via Output() and EventEmitter

یکی دیگر از روش های انقال اطلاعات از فرزند به پدر استفاده از Output میباشد . شویه کار به این صورت است که در کامپوننت فرزند به اجرا یک رویداد داده به کامپوننت پدر انتقال خواهد یافت

#parent.component.ts

import { Component } from '@angular/core';
@Component({
  selector: 'app-parent',
  template: `
    Message: {{message}}
    <app-child (messageEvent)="receiveMessage($event)"></app-child>
  `,
  styleUrls: ['./parent.component.css']
})
export class ParentComponent {
  constructor() { }
  message:string;
  receiveMessage($event) {
    this.message = $event
  }
}

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

  <app-child (messageEvent)="receiveMessage($event)"></app-child>

همان طور که مشخص است receiveMessage یک تابع میباشد که یک ارگومان از نوع event را ازسال میکند پس درون .ts باید این تابع را ایجاد کنیم

  receiveMessage($event) {
    this.message = $event
  }

تابع فوق وقتی ایجاد میشود که یک رویداد از کامپوننت فرزند صادر گردد . حال وارد کامپوننت فرزند میشویم

#child.component.ts

import { Component, Output, EventEmitter } from '@angular/core';
@Component({
  selector: 'app-child',
  template: `
      <button (click)="sendMessage()">Send Message</button>
  `,
  styleUrls: ['./child.component.css']
})
export class ChildComponent {
  message: string = "Hola Mundo!"
  @Output() messageEvent = new EventEmitter<string>();
  constructor() { }
  sendMessage() {
    this.messageEvent.emit(this.message)
  }
}

با ستفاده از دستور output رویدادی را که در کامپوننت پدر تعریف شده بود را مینویسیم و سپس در رویداد کلیک دکمه

   this.messageEvent.emit(this.message)

تابع پدر را فراخوانی کرده و مقدرا message را پاس خواهیم داد

Unrelated Components: Sharing Data with a Service

در تمامی روش های بالا باید یک رابطه پدر و فرزندی بین کامپوننت ها وجود داشته باشد . ولی فرض کنید که هیج ارطباتی بین این دو وجود ندارد!! برای این کار از سرویس ها استفاده میکنیم . ابتدا سرویس زیر را ایجاد کنید

#data.service.ts

import { Injectable } from '@angular/core';
import { BehaviorSubject } from 'rxjs/BehaviorSubject';
@Injectable()
export class DataService {
  private messageSource = new BehaviorSubject<string>("default message");
  currentMessage = this.messageSource.asObservable();
  constructor() { }
  changeMessage(message: string) {
    this.messageSource.next(message)
  }
}

این سرویس باید در هر دو کامپوننت تزریق شود

import { Component, OnInit } from '@angular/core';
import { DataService } from "../data.service";
@Component({
  selector: 'app-parent',
  template: `
    {{message}}
  `,
  styleUrls: ['./sibling.component.css']
})
export class ParentComponent implements OnInit {
  message:string;
  constructor(private data: DataService) { }
  ngOnInit() {
    this.data.currentMessage.subscribe(message => this.message = message)
  }
}

در کامپوننت اول با دستور

this.data.currentMessage.subscribe(message => this.message = message)

مقدار داده را از سرویس میخوانیم . حال سراغ کامپوننت دم میرویم

import { Component, OnInit } from '@angular/core';
import { DataService } from "../data.service";
@Component({
  selector: 'app-sibling',
  template: `
    {{message}}
    <button (click)="newMessage()">New Message</button>
  `,
  styleUrls: ['./sibling.component.css']
})
export class SiblingComponent implements OnInit {
  message:string;
  constructor(private data: DataService) { }
  ngOnInit() {
    this.data.currentMessage.subscribe(message => this.message = message)
  }
  newMessage() {
    this.data.changeMessage("Hello from Sibling")
  }
}

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

this.data.changeMessage("Hello from Sibling")

با این دستور مقدار دهی در سرویس انجام شد . حال در هر دو کامپوننت مقدرا Hello from Sibling چاپ میشود . امیدوارم توانسته باشم مطلب مفیدی را به اشتراک گزاشته باشم

--با استفاده از لینک بالا میتوانید کلیه توضیحات را کامل وخیلی روان تر مطالعه کنید


سبحان مظفری
سبحان مظفری

I am sobhan mozafari from Iram . I am working with Microsoft Technologies Like ASP.NET MVC , C# and SQL Server . I Interested in Node.js and Google Could computing and my favorite C++ .

نظرات