روزنوشته های فربد صالحی

درباره زندگی و برنامه نویسی

۲ مطلب در تیر ۱۳۹۹ ثبت شده است

انتقال اطلاعات از یک کامپوننت به کامپوننت دیگر در Angular

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

 

الف) وقتی کامپوننت‌ها در وضعیت «والد/فرزند» هستند

@Component({
  selector: 'app-child',
  template: `
    <p> {{ username }}'s code is: {{ userCode }}<p>
    <p> 
        <button 
            (click)="sendMessage('Hello from {{ username }}')"> 
                    Send Message 
        </button> 
    </p>
  `
})
export class ChildComponent {
  @Input() userCode: number;
  @Input('name') username: string;
  @Output() sendInfo = new EventEmitter<string>();

  sendMessage(message: string) { 
     this.sendInfo.emit(message); 
  }
}

در قطعه کد بالا، کامپوننت ChildComponnet تعریف شده و دارای دو ویژگی userCode و username هستش که قبل از هر دوی اونها Input@ قرار دادیم تا مشخص کنه انتظار داریم مقدارشون از بیرون از این کامپوننت وارد بشه. یه نکته‌ی ریز هم در این کد استفاده از Input('name')@ هستش و معنیش اینه که کامپوننت‌های دیگه این ویژگی رو با نام name شناسایی و مقداردهی خواهند کرد (همونطور که در کد پایین این کار انجام شده)، هر چند که در داخل خود این کامپوننت از username برای ارجاع بهش استفاده میشه. 

در قطعه کد پایین، کامپوننت ParentComponent تعریف شده که در بخش template اش با استفاده از تگ <app-child>، کامپوننتِ قطعه کد قبلی رو در یک حلقه‌ی for فراخوانی کرده. در اینجا نحوه‌ی انتقال داده به ChildComponent با استفاده از [userCode] و [name] واضح و روشنه. 

@Component({
  selector: 'app-parent',
  template: `
    <app-child *ngFor="let user of users" 
                    [userCode]="user.code"  
                    [name]="user.username"
                    (sendInfo)="onGetInfo($event)">
    </app-child>
  `
})
export class ParentComponent {

  users = Users;
  userMessage: string;

  onGetInfo(message: string) {
     this.userMessage = message;
  }

}

اما اگه بخوایم برعکس عمل کنیم چطور؟ یعنی داده رو از ChildComponent به ParentComponent منتقل کنیم. تو ChildComponent داریم: 

 @Output() sendInfo = new EventEmitter<string>();

ChildComponent هر جا که لازم بود از طریق این EventEmitter می‌تونه یه رویداد یا event تعریف شده تو کامپوننت والد خودش رو فراخوانی کنه و داده‌ها رو به شکل پارامتر به اون بفرسته. همونطور که در عبارت <EventEmitter<string مشخص شده، یه پارامتر از نوع string ارسال می‌کنه. در اینجا این پارامتر، message هستش و همون داده‌ایه که می‌خوایم منتقلش کنیم:

 sendMessage(message: string) { 
   this.sendInfo.emit(message);   
 }

این پارامترها از هر نوع و به هر تعداد می‌تونن باشن. حالا برای اینکه تو کامپوننت والد این مقدار دریافت بشه، تو تمپلیت ParentChild داریم:

(sendInfo)="onGetInfo($event)"

که یعنی هر موقع sendInfo تو ChildComponent رو emit کردن، ()onGetInfo توی ParentChild فراخوانی بشه و پارامتر هم از طریق event$ ارسال بشه:

onGetInfo(message: string) {
   this.userMessage = message;
}

در حالت خیلی کلی میشه گفت در این روش، از Input@ برای ورود داده و از Output@ برای خروج داده استفاده میشه. 

 

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

تو این حالت هر کامپوننت route خودش رو داره. وقتی می‌خوایم یک یا چند پارامتر رو منتقل کنیم، خیلی راحت میشه از queryها در route استفاده کرد. مثلا اگه بخوایم دو تا پارامتر به نام‌های id و category رو از ProducstListComponent به ProductDetailComponent ارسال کنیم:

 
  this.router.navigate(
          ['/product-detail'], 
          {
             queryParams: { id: '3', category = 'mobile'} 
          }
  );
  

و اگه بخوایم تو ProductDetailComponent این پارامترها رو دریافت کنیم:

productId: number;
productCategory: string;
 
ngOnInit() {
    this.route.queryParams.subscribe(params => {
       this.productId= +params['id'];
       this.productCategory = params['category'];
    });
}

 

اما گاهی نیاز داریم که تعداد زیادی پارامتر یا حتی مثلا لیستی از اشیا رو منتقل کنیم به کامپوننت بعدی. در این حالت استفاده از query ها نه راحت هستش نه منطقی. در این حالت می‌تونیم از ویژگی state استفاده کنیم که از نسخه‌ی 7.2 به Angular اضافه شده. برای این‌ کار در ProductsListComponent برای انتقال لیست sameProductsList خواهیم داشت:

this.router.navigate(
              ['/product-detail'], 
              {state: {sameProds: sameProductsList}}
);

سپس برای دریافت این لیست در ProductDetailComponent:

sameProducts: any[];

ngOnInit() {

    const currentNavigationState = 
             this.router.getCurrentNavigation().extras.state;

    if (currentNavigationState) {

      this.sameProducts = currentNavigationState.sameProds;

    } 
 }

 

۰ نظر
فربد صالحی

سرازیریِ انتخاب

 

مساله‌ی «انتخاب» یکی از مسائلیه که زیاد در موردش فکر و صحبت شده، تا جایی که خیلی‌ها معتقدن شاید بزرگ‌ترین تفاوت انسانها در انتخاب‌های متفاوتیه که در طول زندگی‌شون انجام می‌دن.

همگی می‌دونیم که در مورد بعضی از شرایط زندگی، حداقل در لحظه‌ی تولد، امکان انتخاب نداریم. مثل سال و محل تولد، خانواده‌ای که درش به دنیا میایم و حتی اسمی که برامون انتخاب میشه. اما بقیه‌ی مسائل چطور؟ در این زمینه چند نکته به ذهن من می‌رسه.

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

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

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

در بقیه‌ی مسائل زندگی هم این دو شرط قابل بررسی هستن. میشه ورود یه جوون ۱۸ ساله به دانشگاه رو انتخاب خودش دونست؟ اون جوون چه مسیرهایی رو برای زندگی می‌شناخته و چه شناختی از خودش و علائقش داشته که ادامه‌ی تحصیل رو انتخاب کرده؟ در انتخاب رشته‌ی تحصیلیش چطور؟ سرفصل‌ِ درس‌ها و آینده‌ی شغلی رشته‌ها رو درست و کامل می‌شناخته؟ با علایق تحصیلی و کاری خودش آشنا بوده؟ اگر هم از همه‌ی این موارد مطلع بوده، آیا توان علمی و شاید مهم‌تر ازون، توان تست‌زنیش برای قبول شدن تو رشته‌ای که انتخاب کرده کافی بوده؟

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

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

 

 

 

 

۰ نظر
فربد صالحی