روش های اشتراک داده بین کامپوننت های انگولار | راهنمای کاربردی


نوشتن کامپوننتهای کوچک در اغلب موارد یک روش خوب برای مدیریت کد در انگولار (Angular) محسوب میشود. زمانی که شروع به نوشتن کامپوننتهای کوچک میکنید، باید روشهایی برای اشتراک داده بین کامپوننت های انگولار در نظر بگیرید. پیش از آن که به بررسی روشهای این اشتراک داده بین کامپوننتها بپردازیم، باید رابطه بین کامپوننتها را تعریف کنیم.
پنج روش برای اشتراک داده بین کامپوننتهای انگولار وجود دارد:
- از کامپوننت والد به فرزند
- از کامپوننت فرزند به والد
- اشتراک داده بین کامپوننتهای همنیا
- اشتراک داده با استفاده از مشخصه ViewChild
- اشتراک داده بین کامپوننتهای نامرتبط
در ادامه به بررسی و توضیح هر یک از این روشها خواهیم پرداخت.
از کامپوننت والد به فرزند
زمانی که ()Input@ را در کامپوننت فرزند تعریف کنید، مقدار مورد نظر را از کامپوننت مستر یا والد دریافت میکند.
پیش از اشتراک داده بین کامپوننتها ابتدا باید مدل دادههای خود را با استفاده از اینترفیسها تعریف کنیم. در کد زیر اینترفیس Product را با فیلدهای الزامی productID و productName برخی فیلدهای اختیاری تعریف کردهایم:
اکنون اینترفیس Product را در کامپوننت والد خود ایمپورت میکنیم و سپس قالب (Tempate) را میسازیم. این قالب شامل یک شناسه محصول و یک نام محصول است. سپس نام محصول را با کامپوننت فرزند به اشتراک میگذاریم. زمانی که کامپوننت فرزند، نام محصول را بهروزرسانی کند، باید دادهها را به دوباره به کامپوننت والد بازگشت دهیم. بنابراین کد کامپوننت والد به صورت زیر است:
کد کامپوننت فرزند نیز چنین است:
اینک دکوراتور زیر را در کامپوننت فرزند تعریف میکنیم. childToMaster نام مشخصهای است که میخواهیم از کامپوننت والد به اشتراک بگذاریم. دکوراتور Input به وضوح مشخص میسازد که کامپوننت فرزند انتظار مقدار را از کامپوننتهای والد دارد.
در کامپوننت والد، مشخصه childToMaster را تعیین خواهیم کرد.
اکنون مشخصه product.productName را با کامپوننت فرزند به اشتراک میگذاریم. زمانی که شروع به نوشتن productName بکنید، به صورت خودکار با کامپوننت فرزند به اشتراک گذاشته میشود.
کامپوننت فرزند به والد
برای اشتراک دادهها از فرزند به والد به دکوراتور Output نیاز داریم. در کامپوننت فرزند باید دکوراتور output را به صورت زیر تعریف کنیم:
اکنون باید این مشخصه را با کامپوننت والد به اشتراک بگذاریم. بنابراین اشتراک دادهها از کامپوننت فرزند به والد نیازمند ارسال یک رویداد با مقدار به کامپوننت والد است. این رویداد میتواند بر اساس یک نقطه تحریک (Trigger) ارسال شود. در این مثال ما این کار را با استفاده از رویداد کلیک شدن یک دکمه انجام میدهیم. رویداد sendToParent در زمان کلیک شدن دکمه فراخوانی میشود.
اکنون باید childtoParent را به مشخصه تگ child در کامپوننت والد مربوط سازیم.
زمانی که این مقدار به دست کامپوننت والد برسد، آن را تعیین میکنیم:
اینک میتوانیم تغییر یافتن نام محصول را در کامپوننت والد ببینیم.
اشتراک داده بین کامپوننتهای همنیا
اشتراک داده بین همنیاها با استفاده از دو رویکرد که قبلاً توضیح دادیم، انجام میشود. یعنی ابتدا دادهها به وسیله دکوراتور Output از فرزند به سمت والد به اشتراک گذاشته میشوند و سپس از آن والد با استفاده از دکوراتور Input به همنیای دیگر ارسال میشوند. از این رو همنیاها میتوانند از طریق کامپوننتهای والد با همدیگر صحبت کنند.
اشتراک داده با استفاده از دکوراتور ViewChild
دکوراتور ViewChild به کامپوننت فرزند امکان میدهد که درون کامپوننت والد تزریق شود. از این رو، این دکوراتور قدرت زیادی دارد.
کامپوننتهای والد با استفاده از دکوراتور ViewChild میتوانند متدها و مشخصههای فرزند را کنترل کنند. بین ترتیب والد میتواند پس از رویداد view init به مشخصهها دسترسی داشته باشد. این بدان معنی است که باید یک قلاب چرخه عمری ngAfterViewInit را پیادهسازی کنیم تا بتوانیم مشخصهها را در کامپوننتهای والد دریافت کنیم.
در کد فوق ViewChild در کامپوننت فرزند تعریف شده است. ViewChild موجب میشود که در کامپوننت والد یک ارجاع به کامپوننت فرزند داشته باشیم. همچنین مقدار masterName فرزند را در productName والد تعیین میکند.
اشتراک دادهها بین کامپوننتهای نامرتبط
زمانی که هیچ ارتباطی بین کامپوننتها وجود نداشته باشد، نمیتوانیم دادهها را با استفاده از چهار روش که در بخش فوق اشاره کردیم به اشتراک بگذاریم. این موضوع زمانی اتفاق میافتد که کامپوننتها در ماژولهای متفاوتی باشند. سناریوهای دیگری وجود دارند که شما لیستی از محصولها دارید و روی یک محصول خاص کلیک میکنید و سپس به کامپوننتهای جزییات محصول هدایت میشوید. در این نوع سناریوها باید از سرویسهای داده برای اشتراک دادهها بین کامپوننتها استفاده کنید.

برای ایجاد سرویس داده باید BehaviorSubject را تعریف کنیم. مقدار کنونی و آخرین مقدار را ذخیره میکند. به دلایل زیر همواره بهتر است از BehaviorSubject استفاده کنیم:
- به صورت خودکار آخرین مقدار را هر زمان که ثبت شود بهروزرسانی میکند.
- در زمان فراخوانی متد ()getValue همواره آخرین مقدار را بازگشت میدهد.
نیازی به فراخوانی بعدی نیست و کافی است متد set و get را برای دریافت مقدار مورد استفاده قرار دهیم.
در سرویس دادهها یک messageSource به عنوان BehaviorSubject ایجاد کردهایم. این messageSource یک مقدار editDataDetails با نوع any میپذیرد. امکان ساخت editDataDetails به عنوان نوع اینترفیس محصول نیز وجود دارد که رویه مناسبی تصور میشود. متد changeMessage نیز مقدار observable-ها را تعیین میکند.
اکنون باید این سرویس را با کامپوننتها یعنی جایی که میخواهیم مقادیر را دریافت و تنظیم کنیم، به اشتراک بگذاریم. متد changeMessage را با مقادیر به عنوان پارامتر فراخوانی کنید تا مقدار مورد نظر تعیین شود. در کامپوننتی که میخواهید مقدار دریافت شود، آن را ثبت نام (subscribe) کنید. زمانی که ثبت نام کردید، همواره آخرین مقدار را در زمان هر گونه تغییر در کد دریافت میکنید.
ایجاد متدهای Get و Set مشخصه و BehaviourSubject
در مثال قبل میتوانیم با استفاده از اینترفیس Product و ساخت متدهای getter و setter با متد زیر، عملکرد بهتری را شاهد باشیم.
اکنون از کامپوننتی که میخواهیم دادهها را تنظیم کنیم، عملیات set را اجرا میکنیم. با ثبت نام در متد get میتوانیم آخرین مقدار دادههای محصول را دریافت کنیم.
استفاده از ReplaySubject
در بسیاری از سناریوها به subject-ها برای یادآوری مقادیر قدیمی نیاز داریم. برای نمونه در زمان رتبهدهی به محصول باید دادهها را به موتور تحلیلی بدهیم تا بررسی کند سه محصول انتخابی آخر کاربر کدامها بوده است. برای دستیابی به این حالت میتوانیم ReplaySubjects را به صورت زیر ایجاد کنیم:
ارسال دادهها بین کامپوننتها با استفاده از Angular Route
اگر از ناوبری روتر برای رفتن به کامپوننتهای دیگر استفاده میکنید، میتوانید آن را در متد navigate روتر ارسال کنید:
در کد فوق، id محصول را در پارامترهای کوئری در زمان مسیریابی کامپوننت به جزییات محصول تنظیم میکنیم. سپس در کامپوننت جزییات آن id را در سازنده به دست میآوریم.
چنان که میبینید در کد فوق، در کامپوننت دوم، productID را به دست آوردهایم. از آنجا که این دادهها همواره از طریق URL ارسال میشوند، در معرض دید کاربر نهایی قرار دارند. بنابراین نباید اقدام به ارسال اطلاعات حساس بکنید. با این حال، همواره میتوانید از این روش برای ارسال فیلدهای کوچک و دادههای عادی استفاده کنید.
سخن پایانی
در این مقاله 5 روش برای اشتراک داده بین کامپوننتهای انگولار معرفی کردیم.
این که از کدام یک از این روشها استفاده میکنید، به رابطه بین کامپوننتها بستگی دارد. استفاده از هر یک از این رویکردها برخی مزیتها و معایب نسبت به انواع دیگر دارد.
به نظرم خیلی خوب توضیح داده شده. ممنون