<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
    <channel>
        <title>نوشته های رهام رفیعی تهرانی</title>
        <link>https://virgool.io/feed/@roham.tehrani</link>
        <description>برنامه نویسی یک شغل نیست، یک هنره.</description>
        <language>fa</language>
        <pubDate>2026-06-07 00:33:48</pubDate>
        <image>
            <url>https://files.virgool.io/upload/users/52004/avatar/TBZ1jE.jpg?height=120&amp;width=120</url>
            <title>رهام رفیعی تهرانی</title>
            <link>https://virgool.io/@roham.tehrani</link>
        </image>

                    <item>
                <title>تجربه ارتقای رم به کمک هوش مصنوعی</title>
                <link>https://virgool.io/@roham.tehrani/%D8%AA%D8%AC%D8%B1%D8%A8%D9%87-%D8%A7%D8%B1%D8%AA%D9%82%D8%A7%DB%8C-%D8%B1%D9%85-%D8%A8%D9%87-%DA%A9%D9%85%DA%A9-%D9%87%D9%88%D8%B4-%D9%85%D8%B5%D9%86%D9%88%D8%B9%DB%8C-eaf6pctaiztm</link>
                <description>چند روز پیش وقتی دستور ng serve رو اجرا میکردم، سیستمم هنگ میکرد. دلیلش بزرگی نرم افزار بود. یک روش پیدا کردم و راجع بهش مقاله نوشتم. اگر دوست داشتین میتونین اینجا مطالعه کنین.رفع خطای JavaScript heap out of memoryنرم افزار اجرا شد ولی سیستم دائم crash میکرد. طبق تجربیات قبلی حدس زدم مشکل از کمبود RAM هست. به کمک هوش مصنوعی بررسی کردم و بررسی ها ادامه پیدا کرد تا رسیدم به مدل دقیق RAM مورد نیازم.این مقاله رو بیشتر برای کسانی می نویسم که دور از فضای هوش مصنوعی هستند و هنوز نمی دونند چه ابزاری رو تجربه و استفاده نمی کنند. در حالیکه بسیار ساده ست.دو تا سوال ازش پرسیدم:یک توضیح کلی داد:در اوبونتو از ترمینال می‌توانید اطلاعات سخت‌افزاری را ببینید:بعد جدا جدا هر سوال رو جواب داد با جزئیات دقیق:جواب سوال اولمشاهده مقدار RAMیا دستور برای جزئیات بیشتر:اگر dmidecode نصب نبود:جالبه که حتی دستورات جانبی مورد نیاز رو هم میگه.جواب سوال دوممشاهده مدل لپ‌تاپبرای مشاهده سازنده و مدل:یا بدون نیاز به sudo:این جواب یعنی همه حالت های ممکن رو در وضعیت پیش روی من در نظر گرفته!در ادامه حتی جواب های تکمیل کننده هم اضافه کرد:مشاهده خلاصه مشخصات سیستماگر ابزار inxi را نصب کنید:خروجی شامل مدل لپ‌تاپ، CPU، RAM، گرافیک، دیسک و سایر اطلاعات خواهد بود.اگر خروجی این دستورات را اینجا بفرستید، مشخصات را برایتان تفسیر می‌کنم.دستورهای اول هر جواب رو اجرا کردم و تا اینجا فهمیدم مدل لپ تاپم چیه و چقدر RAM داره. در ادامه ازش پرسیدم:جوابی رو که با کلی سرچ در گوگل و سایت های مختلف در بهترین حالت میتونستم پیدا کنم رو گذاشت جلوی چشمم:مدل لپ‌تاپ شما: ASUS VivoBook X545FBطبق منابع مختلف ارتقای RAM، این مدل معمولاً حداکثر 24 گیگابایت RAM را پشتیبانی می‌کند. ساختارش معمولاً به این شکل است:یک مقدار RAM به مادربرد لحیم شده (Onboard) است.یک اسلات RAM قابل ارتقا دارد.اسلات قابل ارتقا معمولاً تا 16GB DDR4 SO-DIMM را پشتیبانی می‌کند.اگر دستگاه شما 8GB رم لحیم‌شده داشته باشد ⇒ مجموعاً 24GB (8+16) می‌شود.اما بعضی نسخه‌های X545FB با 4GB رم لحیم‌شده عرضه شده‌اند که در آن حالت حداکثر عملی ممکن است 20GB (4+16) باشد. برخی منابع حتی 12GB یا 16GB را برای بعضی کانفیگ‌ها ذکر کرده‌اند.برای اینکه دقیقاً بگویم لپ‌تاپ خودت تا چند گیگ می‌رود، این دستور را در اوبونتو اجرا کن:یاخروجی را اینجا بفرست. از روی آن مشخص می‌شود:چند اسلات داریچقدر RAM لحیم‌شده استالان چه ماژولی نصب استحداکثر ارتقای واقعی سیستم تو چقدر خواهد بود.منم خروجی رو براش کپی کردم و فرستادم:کامل برام توضیح داد که وضعیت سیستمم چطوریه و یک RAM با ظرفیت 8G یا 16G لازم دارم.آخرش بهم پیشنهاد داد که مدل های RAM که با لپ تاپم سازگار هستند رو برام لیست کنه و حتی در بازار ایران هم لینک خرید برام بفرستهدر نهایت هم سه مدل RAM معرفی کرد ولی لینک خریدهایی که داد چندان جالب نبودند. مجبور شدم خودم در ترب و دیجی کالا و سایت های دیگه مدل ها رو سرچ کنم و فروشنده های با قیمت مناسب رو پیدا کردم.به نظرم دوره سردرگمی در سرچ های اینترنتی تموم شده. دوره هوش مصنوعی هست و بهترین جواب های معادل سه چهار ساعت وقت جستجو رو میشه به کمکش طی چند دقیقه پیدا کرد.به امید روزهای بهترموفق باشید :)</description>
                <category>رهام رفیعی تهرانی</category>
                <author>رهام رفیعی تهرانی</author>
                <pubDate>Mon, 01 Jun 2026 10:00:14 +0330</pubDate>
            </item>
                    <item>
                <title>رفع خطای JavaScript heap out of memory</title>
                <link>https://virgool.io/@roham.tehrani/%D8%B1%D9%81%D8%B9-%D8%AE%D8%B7%D8%A7%DB%8C-javascript-heap-out-of-memory-nuawljjig9ky</link>
                <description>امروز اومدم یک پروژه نسبتا بزرگ رو روی لوکال خودم run کنم که به این خطا برخوردم:گشتم و راه حلش رو پیدا کردم و این مقاله رو به همین بهانه نوشتم.وقتی پروژه‌های بزرگ جاوااسکریپت/تایپ‌اسکریپت را build می‌کنید ( یا در فرآیند serve ) و با خطاهایی مثل این مواجه میشید:چه در Angular چه در پروژه های دیگه مثل React، Next.js و ... یعنی فرایند build با کمبود حافظه RAM مواجه شده و نیاز به فضای حافظه بزرگتری داره.راه حلش اجرای یک دستور ساده است:این دستور یعنی فرآیند build میتونه تا حدود 7 گیگابایت RAM مصرف کنه و احتمال خطای کمبود حافظه کمتر میشه.اگر با لینوکس کار میکنید یک نکته خیلی مهم داره که یک ربعی من رو سرکار گذاشت.در لینوکس متغیرهای محیطی به حروف بزرگ و کوچک حساس هستند.پس، باید اینطوری نوشته بشه:اگر خط زیر رو بنویسید، یه ربع ساعتی مثل من سر کار میرید:در لینوکس، Node.js فقط NODE_OPTIONS را میشناسه.به امید روزهای بهتر‌:)موفق باشید :)</description>
                <category>رهام رفیعی تهرانی</category>
                <author>رهام رفیعی تهرانی</author>
                <pubDate>Sun, 31 May 2026 13:22:04 +0330</pubDate>
            </item>
                    <item>
                <title>راهنمای استفاده از ngx-translate در Angular 21</title>
                <link>https://virgool.io/@roham.tehrani/%D8%B1%D8%A7%D9%87%D9%86%D9%85%D8%A7%DB%8C-%D8%A7%D8%B3%D8%AA%D9%81%D8%A7%D8%AF%D9%87-%D8%A7%D8%B2-ngx-translate-%D8%AF%D8%B1-angular-21-clpgi6rpih38</link>
                <description>شرکت جدیدی که دارم کار میکنم، اولین قدمم چندزبانه کردن کامپوننت های فارسی هست. برای این کار از ngx-translate استفاده کردم. در این مقاله، میخوام تجربه این یک هفته اخیر رو باهاتون به اشتراک بگذارم. تصمیمش هم با من نبود، از قبل گرفته شده بود.در انگولار راه های مختلفی برای چند زبانه کردن اپلیکیشن هست:کتابخانه i18n که built-in خود انگولار هستکتابخانه ngx-translate که از همه پرطرفدارترهکتابخانه transloco که از همه جدیدترهمزایای اصلی ngx-translateتغییر زبان در زمان اجراپشتیبانی از فایل‌های JSONیادگیری آسانمناسب برای پروژه‌های کوچک و بزرگامکان بارگذاری ترجمه‌ها از APIپشتیبانی از پارامترهای داینامیکتنظیمات ngx-translate در نسخه های مختلف Angular با هم فرق میکنه. یک قسمت از تفاوت ها هم در مورد استفاده از NgModules و مدل های جدیدتر Standalone هست.این مقاله مربوط به Angular21 و مدل های Zoneless ( یا همون Standalone) هست.نصب پکیج هاابتدا کتابخانه‌های موردنیاز را نصب میکنیم:ساخت فایل های ترجمهدر پوشه assets فایل‌های زیر را ایجاد کنید:محتوای فایل انگلیسی en.json:محتوای فایل فارسی fa.json:پیکربندی در انگولار:در فایل app.config.ts به لیست Providers ، مقدار provideTranslateService رو اضافه میکنیم :در این مرحله خطا میده و ریکوئست بارگذاری فایل ترجمه خطای ۴۰۴ میده/assets/i18n/fa.jsonبرای حل این مشکل باید در فایل angular.json و در قسمت build ، دایرکتوری src/assets رو به لیست assets اضافه کنیم:محتوای app.html رو هم به صورت زیر تغییر میدیم:خطای دیگه ای که میگیریم ، مربوط به translate pipe هست که استفاده کردیم. باید این pipe رو در کامپوننت import کنیم:نتیجه رو در صفحه اصلی می بینیم:استفاده از ngx-translate در کامپوننتاول باید سرویس TranslateService رو وارد کامپوننت کنیم.بعد هر جا نیاز داشتیم متن ها رو به روش زیر ترجمه کنیم:\استفاده از زبان فعلی در کامپوننت هافقط کافیه متغیری مثلا به اسم currentLang تعریف کنیم:و اون رو در ngOnInit مقداردهی کنیم:میتونیم اون رو در تمپلت هم استفاده کنیم:آگاهی از تغییر زبان فعلی در کامپوننتبرای آگاهی از تغییر زبان فعلی در کامپوننت کافیه مثل زیر عمل کنیم:به امید روزای بهتر :)موفق باشید :)</description>
                <category>رهام رفیعی تهرانی</category>
                <author>رهام رفیعی تهرانی</author>
                <pubDate>Sun, 31 May 2026 13:21:36 +0330</pubDate>
            </item>
                    <item>
                <title>تنظیم preview روی vscode</title>
                <link>https://virgool.io/@roham.tehrani/%D8%AA%D9%86%D8%B8%DB%8C%D9%85-preview-%D8%B1%D9%88%DB%8C-vscode-f1vbp1qov0fu</link>
                <description>وقتی vs code رو برای اولین بار نصب میکنی یک رفتاری از خودش بروز میده که خیلی رو مخه. هر فایلی رو که باز میکنی ولی هیچ تغییری توش نمیدی، یک فایل جدید دیگه باز کنی، فایل قبلی رو حذف میکنه.چون چند سال بود از اول vs code رو نصب نکرده بودم یادم رفته بود این رفتار رو داره. تنبلیم میومد بگردم دنبال تنظیمش. یه کم سرچ کردم تا همه چیز برام یادآوری شد. تصمیم گرفتم اینجا بنویسمش که یادم نره و طولانی تر تو ذهنم بمونه. شما هم اگر یه وقت نیازتون شد، با خواندن این مقاله طولانی تر یادتون بمونه.نرم افزار vs code به صورت پیش‌فرض فایل رو در حالت preview باز میکنه. اگر باز شدن فایل به صورت preview نباشه میتونید چند تا فایل رو بدون اینکه تغییری در اونها بدید باز کنید.برای برداشتن این حالت پیش‌فرض باید به تنظیمات برید:یک shortkey برای باز کردن settings به صورت پیش‌فرض هست : ctrl+,در بخش تنظیمات دنبال عبارت زیر بگرد:و این گزینه را خاموش کن:یا در settings.json:اگر فایل ها رو با کمک ctrl+p باز میکنی ( از فضای quick open ) ، این گزینه رو هم خاموش کن:یک رفتار دیگه ای که در vs code هست، دبل کلیک روی فایل برای باز کردنش هست. وقتی روی یک فایل دبل کلیک کنید، خود بخود به حالت preview باز نمیشه و میتونید فایل دیگه ای رو هم کنارش باز کنید.تنظیم پیشنهادی برای برنامه‌نویسیبا این تنظیمات هر فایلی که باز کنی به صورت Tab دائمی باز می‌شود و VS Code دیگه فایل قبلی رو نمی‌بنده.به امید روزهای بهتر‌:)موفق باشید :)</description>
                <category>رهام رفیعی تهرانی</category>
                <author>رهام رفیعی تهرانی</author>
                <pubDate>Sat, 30 May 2026 11:20:25 +0330</pubDate>
            </item>
                    <item>
                <title>کار نکردن:host-context روی مرورگر firefox</title>
                <link>https://virgool.io/@roham.tehrani/%DA%A9%D8%A7%D8%B1-%D9%86%DA%A9%D8%B1%D8%AF%D9%86host-context-%D8%B1%D9%88%DB%8C-%D9%85%D8%B1%D9%88%D8%B1%DA%AF%D8%B1-firefox-dceh8ong36ii</link>
                <description>امروز میخواستم با یک selector به اسم :host-context کار کنم. ولی متوجه شدم روی فایرفاکس کلا پشتیبانی نمیشه. برای همین تصمیم گرفتم یک مقاله در موردش بنویسم.شبه‌کلاس :host-context() بخشی از Web Components و Shadow DOM است، اما پشتیبانی آن در مرورگرها یکدست نیست. به‌خصوص در Firefox، :host-context() برای مدت طولانی پشتیبانی نشده و در بسیاری از سناریوها هنوز قابل اتکا نیست.مثلاً اگر چنین چیزی دارید:ممکنه در Chrome کار کند ولی در Firefox اعمال نشه.راه‌حل‌های جایگزین۱. انتقال کلاس به خود Host (پیشنهادی)به جای:از:استفاده کنید و کلاس رو مستقیماً روی کامپوننت قرار دهید:۲. استفاده از CSS Custom Propertiesروی والد:و داخل Shadow DOM:متغیرهای CSS از Shadow Boundary عبور می‌کنند و این روش معمولاً بهترین جایگزین برای :host-context() است.۳. تنظیم Attribute یا Class با JavaScriptاگر باید وضعیت والد را تشخیص دهید:و در CSS:</description>
                <category>رهام رفیعی تهرانی</category>
                <author>رهام رفیعی تهرانی</author>
                <pubDate>Sat, 30 May 2026 09:20:39 +0330</pubDate>
            </item>
                    <item>
                <title>نصب پکیج های npm در محیط اینترانت داخلی</title>
                <link>https://virgool.io/@roham.tehrani/%D9%86%D8%B5%D8%A8-%D9%BE%DA%A9%DB%8C%D8%AC-%D9%87%D8%A7%DB%8C-npm-%D8%AF%D8%B1-%D9%85%D8%AD%DB%8C%D8%B7-%D8%A7%DB%8C%D9%86%D8%AA%D8%B1%D8%A7%D9%86%D8%AA-%D8%AF%D8%A7%D8%AE%D9%84%DB%8C-unk03rmpmmrb</link>
                <description>امروز(!) مجبور شدم دنبال یک راه حل برای نصب پکیج های npm در محیط اینترانت داخلی بگردم و راه حل خوبی پیدا کردم.این راه حل رو شرکت runflare.com ارائه کرده و واقعا دستشون درد نکنه.نصب پکیج‌ها با Mirror در رانفلرهنگام نصب پکیج‌ها، اگر نمی‌خواهید فایل‌های mirror را به صورت global تنظیم کنید می‌توانید از روش زیر نصب را کامل کنید.در این مثال نصب پکیج اکسپرس(express) را می‌بینید:تنظیم mirror به صورت global در لینوکس، ویندوز و مکدرصورتی که نیاز به دستورات اضافه در npm ندارید می‌توانید از روش زیر تنظیمات را روی global قرار دهید.برای فعال‌سازی mirror، در ترمینال لینوکس و مک و یا در CMD ویندوز دستورات زیر را وارد کنید:حالا مثل همیشه می‌توانید دستور npm install را اجرا کنید و از مخزن mirror رانفلر داخل کشور، داده‌ها را دریافت کنید. برای غیر فعال‌ کردن mirror، دستور زیر را وارد کنید:لینک اصلی مطلب:https://runflare.com/mirrors/npm-mirror/به امید روزهای بهترموفق باشید :)</description>
                <category>رهام رفیعی تهرانی</category>
                <author>رهام رفیعی تهرانی</author>
                <pubDate>Sat, 30 May 2026 09:00:10 +0330</pubDate>
            </item>
                    <item>
                <title>چرا توسعه‌دهندگان Angular هنوز از ::ng-deep استفاده می‌کنند؟</title>
                <link>https://virgool.io/@roham.tehrani/%DA%86%D8%B1%D8%A7-%D8%AA%D9%88%D8%B3%D8%B9%D9%87-%D8%AF%D9%87%D9%86%D8%AF%DA%AF%D8%A7%D9%86-angular-%D9%87%D9%86%D9%88%D8%B2-%D8%A7%D8%B2-ng-deep-%D8%A7%D8%B3%D8%AA%D9%81%D8%A7%D8%AF%D9%87-%D9%85%DB%8C-%DA%A9%D9%86%D9%86%D8%AF-nwmhz1yq1eol</link>
                <description>با وجود اینکه ::ng-deep از نسخه‌های ابتدایی Angular به‌عنوان یک راه‌کار برای نفوذ به سبک‌دهی داخل کامپوننت‌ها معرفی شد و بعدها به‌طور رسمی منسوخ (deprecated) اعلام شد، هنوز هم در بسیاری از پروژه‌های Angular دیده می‌شود. در این مقاله به دلایل ادامه‌دار بودن استفاده از ::ng-deep در سال ۲۰۲۵ می‌پردازیم و راهکارهای جایگزین را بررسی می‌کنیم.۱. چیستی ::ng-deepAngular به‌صورت پیش‌فرض استایل‌های هر کامپوننت را با مکانیزم «انکپسولاسیون» (Encapsulation) ایزوله می‌کند تا سبک‌ها به بیرون از همان کامپوننت نشت نکنند. اما در مواردی که لازم باشد استایلی را از والد به فرزند یا از یک لایه کامپوننت به لایه‌های عمیق‌تر اعمال کنیم (مثلاً هنگام تغییر ظاهر کامپوننت‌های شخص‌ثالث)، دستور ::ng-deep به‌عنوان یک «شکاف» (deep selector) معرفی شد تا بتوان این انکپسولاسیون را موقتاً دور زد./* نمونه استفاده */:host ::ng-deep .mat-button {    background-color: #1976d2;}۲. چرا با وجود منسوخ‌بودن هنوز استفاده می‌شود؟۲.۱. نبود جایگزین کامل و یکپارچهتا امروز Angular راه‌حل رسمی و یکسانی برای تمام حالات پیچیده استایل‌دهی ارائه نکرده است. ابزارهایی مثل :host، :host-context و حتی استایل‌های جهانی (global styles) در برخی موقعیت‌ها کارآمد هستند، اما در بسیاری از حالات، به‌ویژه وقتی با کامپوننت‌های شخص‌ثالث (مثل Angular Material یا PrimeNG) سروکار دارید، این ابزارها ناکافی‌اند.۲.۲. حجم زیاد کدهای قدیمیبسیاری از اپلیکیشن‌های بزرگ و سازمانی از سال‌ها قبل با ::ng-deep نوشته شده‌اند. بازنویسی و حذف تدریجی این دستور در هزاران فایل می‌تواند بسیار زمان‌بر و پرریسک باشد و تیم‌ها ترجیح می‌دهند با همان راه‌کار شناخته‌شده به‌کار ادامه دهند.۲.۳. ریسک بالا در تغییر انکپسولاسیونبرخی تیم‌ها برای دور زدن محدودیت‌های استایل‌دهی، کل انکپسولاسیون را با ViewEncapsulation.None غیرفعال می‌کنند که باعث می‌شود تمام استایل‌ها به‌صورت سراسری اعمال شوند. این رویکرد ریسک تداخل استایل‌ها را افزایش می‌دهد و نگهداری آن دشوار است. بنابراین ::ng-deep همچنان گزینه‌ی کم‌دردسرتر به نظر می‌رسد.۲.۴. پشتیبانی پنهان در Angularهرچند ::ng-deep منسوخ شده، تیم Angular هنوز آن را در هسته‌ی فریم‌ورک نگه داشته و حذف رسمی آن را به آینده نامعلومی موکول کرده است. همین امر توسعه‌دهندگان را مطمئن می‌سازد که فعلاً از کاربرد این دستور در پروژه‌هایشان پشتیبانی ادامه می‌یابد.---۳. معایب استفاده مداوم از ::ng-deep1. فنی بدهی (Technical Debt): انباشت دستور‌های منسوخ در کد باعث پیچیدگی و دشواری نگهداری می‌شود.2. کاهش خوانایی: ورود مکرر ::ng-deep به فایل‌های CSS/SCSS باعث می‌شود کد استایل از اصول مدرن Angular دور شود.3. ریسک در آینده: وقتی فرمان حذف کامل این قابلیت توسط تیم Angular صادر شود، بازنویسی یکباره بخش بزرگی از کد به‌همراه ریسک خطاها خواهد بود.---۴. راهکارهای جایگزین1. استفاده از CSS Variables: تعریف متغیرهای سراسری در :root و استفاده از آن‌ها در کامپوننت‌های مختلف.2. استایل‌دهی از طریق API کامپوننت‌ها: اگر کتابخانه‌ای از شما API یا کلاس‌های کمکی برای سفارشی‌سازی ارائه می‌دهد، به جای دستکاری CSS، از آن استفاده کنید.3. Tailwind CSS یا CSS Modules: با ورود فریم‌ورک‌های جدید، می‌توانید از رویکرد utility-first یا ماژولار برای جداسازی دقیق استایل بهره ببرید.4. تغییر انکپسولاسیون به Shadow DOM: در صورت امکان، از ViewEncapsulation.ShadowDom برای جداسازی واقعی استایل استفاده کنید و با ::part و ::theme استایل‌های لازم را تزریق نمایید.---۵. نتیجه‌گیریدر سال ۲۰۲۵، ::ng-deep هنوز زنده است نه به دلیل مطلوبیت فنی، بلکه به دلیل عملیاتی بودن آن در شرایط خاص و نبود جایگزین یکپارچه. با این حال، توصیه می‌شود برای آینده‌نگری و کاهش بدهی فنی، استفاده از این دستور را به حداقل برسانید، راهکارهای مدرن‌تر را جایگزین کنید و در صورت ادامه‌ی استفاده، به‌خوبی مستندسازی و محدودسازی کنید.---نظر شما چی هست؟ هنوز در پروژه‌های خود از ::ng-deep استفاده می‌کنید؟ راهکار جایگزین شما چه بوده؟ لطفاً تجربیات‌تان را به اشتراک بگذارید!امیدوارم از این مقاله لذت ببرید و براتون مفید باشه.اگر دوست دارید میتونید از طریق صفحه لینکدین با من در ارتباط باشید :)موفق باشید :)</description>
                <category>رهام رفیعی تهرانی</category>
                <author>رهام رفیعی تهرانی</author>
                <pubDate>Thu, 26 Jun 2025 15:27:35 +0330</pubDate>
            </item>
                    <item>
                <title>استفاده از command pattern در انگولار</title>
                <link>https://virgool.io/codenevis/%D8%A7%D8%B3%D8%AA%D9%81%D8%A7%D8%AF%D9%87-%D8%A7%D8%B2-command-pattern-%D8%AF%D8%B1-%D8%A7%D9%86%DA%AF%D9%88%D9%84%D8%A7%D8%B1-ono87lr623qx</link>
                <description>در برنامه‌نویسی رابط کاربری با Angular، اغلب با سناریوهایی مواجه می‌شیم که شامل چندین اقدام پیچیده، مدیریت وضعیت‌ها و تعاملات متعدد با سرویس‌ها هستند. تو این وضعیت، پیاده‌سازی مستقیم منطق در کامپوننت‌ها می‌تونه کد رو نامرتب و سخت کنه برای تست و نگهداری. الگوی Command یک راه‌حل ساختاریافته برای این مشکل ارائه می‌دهد.جدا کردن منطق از UI همیشه خوبه. ولی استفاده از command pattern به مراتب تمیزتر و مرتب تر هست.چون برای جدا کردن منطق از UI به روش های دیگه باید کلی داکیومنت بنویسیم و توضیح بدیم . به نظرم من مزیت روش Command Pattern حذف کلی توضیح و داکیومنت هست. خوبی استفاده پترن ها بجای روش های خودساخته اینه که خیلی کمتر نیاز به داکیومنت و صحبت هست. یک اصطلاح دو کلمه ای به اندازه دو صفحه توضیح کار میکنه.در این مقاله، با نحوه استفاده از الگوی Command در Angular برای سامان‌دهی بهتر به منطق اقدامات پیچیده آشنا میشیم.معرفی الگوی Commandتعریف رسمی: الگوی Command یکی از الگوهای طراحی رفتاری است که یک درخواست را به‌صورت یک شیء کپسوله می‌کند. این الگو به ما اجازه می‌دهد درخواست‌ها را پارامترسازی، صف‌بندی، بازگردانی (undo/redo) و ثبت کنیم.ساختار کلی:هر کلاس Command معمولاً وابسته به یک گیرنده (Receiver) است که کار واقعی را انجام می‌دهد.اول مزایای استفاده از این الگو رو ببینیم و بعد بریم برای پیاده سازیچرا از Command Pattern در Angular استفاده کنیم؟جداسازی منطق از UIاقداماتی مانند ذخیره‌سازی، حذف، ویرایش و ارسال میتونن از کامپوننت‌ها جدا شده و در کلاس‌های مجزا قرار بگیرند.افزایش تست‌پذیریکلاس‌های Command به راحتی قابل تست هستند بدون نیاز به UI.قابلیت undo/redoاجرای مجدد یا لغو اقدامات خیلی ساده‌تر میشه.هماهنگی آسان‌تری بین چند سرویس یا منابع داده ایجاد میشه و مخصوصاً در اپلیکیشن‌های بزرگ با تعامل‌های پیچیده خیلی مفید تره.پیاده‌سازی نمونه در Angularبیاین روی سناریوی «ذخیره یک کاربر» کار کنیمفرض کنید بخواهیم یک کاربر را ذخیره کنیم. این عملیات شامل بررسی وجود کاربر، تماس با API و به‌روزرسانی UI است.۱. تعریف رابط Command:۲. تعریف کلاس ذخیره کاربر:3. استفاده در کامپوننت:پشتیبانی از Undo/Redoاگر بخواهیم undo رر اضافه کنیم، می‌تونیم رابط Command رو گسترش بدیم:و مثلاً در DeleteUserCommand:سازمان‌دهی بهتر با Command Dispatcherبرای مدیریت مرکزی دستورات، می‌توان یک سرویس CommandDispatcher ساخت:و در کامپوننت استفاده کرد:نتیجه‌گیریاستفاده از الگوی Command در Angular یک روش مؤثر برای مدیریت اقدامات پیچیده رابط کاربری به حساب میاد. این الگو با جدا کردن منطق اقدام‌ها از کامپوننت‌ها، باعث میشه کد تمیزتر، منعطف‌تر و تست‌پذیرتر بشه. در پروژه‌های متوسط تا بزرگ، استفاده از این الگو می‌تونه تأثیر زیادی در ساختار و کیفیت کد داشته باشه.امیدوارم از این مقاله لذت ببرید و براتون مفید باشه.اگر دوست دارید میتونید از طریق صفحه لینکدین با من در ارتباط باشید :)موفق باشید :)</description>
                <category>رهام رفیعی تهرانی</category>
                <author>رهام رفیعی تهرانی</author>
                <pubDate>Wed, 11 Jun 2025 18:18:27 +0330</pubDate>
            </item>
                    <item>
                <title>مروری بر ویژگی‌های برجسته انگولار ۲۰</title>
                <link>https://virgool.io/@roham.tehrani/%D9%85%D8%B1%D9%88%D8%B1%DB%8C-%D8%A8%D8%B1-%D9%88%DB%8C%DA%98%DA%AF%DB%8C-%D9%87%D8%A7%DB%8C-%D8%A8%D8%B1%D8%AC%D8%B3%D8%AA%D9%87-%D8%A7%D9%86%DA%AF%D9%88%D9%84%D8%A7%D8%B1-%DB%B2%DB%B0-ddiwn744bydw</link>
                <description>چند روز پیش یک مقاله خواندم در مورد ویژگی های مهم انگولار ۲۰ که قراره در اواخر ماه می ۲۰۲۵ منتشر بشه. در این مقاله میخوایم این ویژگی‌های جدید و جذاب رو مرور کنیم. ظاهرا نسخه ۲۰ انگولار قراره با تغییرات اساسی و بهبودهای قابل توجهی همراه بشه که توسعه‌دهندگان رو حسابی هیجان‌زده کرده.۱. خداحافظ Zone.js، سلام به Zoneless Change Detectionانگولار از نسخه ۱۸ به سمت حذف وابستگی به Zone.js حرکت کرده و سیستم جدیدی به نام &quot;Zoneless Change Detection&quot; معرفی کرده. در نسخه ۲۰ قرار واقعا Zone.js رو حذف کنید. این تغییر باعث می‌شه:عملکرد اولیه و زمان اجرا سریع‌تر بشهحجم بسته‌ها کاهش پیدا کنهاشکال‌زدایی ساده‌تر و کارآمدتر بشهبرای استفاده از این قابلیت، کافیه Zone.js رو از پروژه‌تون حذف کنید و از ابزارهایی مثل ChangeDetectorRef یا ApplicationRef برای مدیریت تغییرات استفاده کنید.۲. فرم‌های مبتنی بر Signalsیکی از ویژگی‌های مورد انتظار در انگولار ۲۰، معرفی فرم‌های مبتنی بر Signals هست. این فرم‌ها:با سیستم واکنش‌پذیری انگولار هماهنگ‌تر هستندبرای فرم‌های پیچیده مقیاس‌پذیری بهتری دارندبه‌صورت خودکار با استفاده از computed signals به‌روزرسانی می‌شناین تغییرات باعث می‌شن مدیریت فرم‌ها ساده‌تر و کارآمدتر بشه.۳. کامپوننت‌های بدون Selectorانگولار در حال بررسی امکان استفاده از کامپوننت‌هایی بدون نیاز به تعریف selector هست. این ویژگی:کدهای اضافی رو کاهش می‌دهمدیریت وابستگی‌ها رو ساده‌تر می‌کنهتوسعه کامپوننت‌ها رو سریع‌تر می‌کنهاین تغییر می‌تونه تجربه توسعه‌دهندگان رو بهبود بده و کدها رو تمیزتر کنه.۴. جایگزینی Karma با ابزارهای مدرن‌تربا کنار گذاشتن Karma، انگولار به دنبال جایگزین‌هایی مثل Web Test Runner، Jest و Vitest هست. این ابزارها:سرعت اجرای تست‌ها رو افزایش می‌دنتجربه بهتری برای توسعه‌دهندگان فراهم می‌کننبا محیط‌های مدرن‌تر سازگارتر هستنداین تغییرات باعث می‌شن فرآیند تست‌نویسی ساده‌تر و مؤثرتر بشه.۵. پشتیبانی از Nitro در Angular CLIانگولار در حال بررسی ادغام Nitro، یک سیستم ساخت مبتنی بر Rust، با Angular CLI هست. این ادغام:سرعت ساخت و توسعه پروژه‌ها رو افزایش می‌دهبهینه‌سازی‌های بهتری ارائه می‌دهتجربه توسعه‌دهندگان رو بهبود می‌بخشهاین تغییر می‌تونه زمان توسعه رو کاهش بده و بهره‌وری رو افزایش بده.جمع‌بندیانگولار ۲۰ با تمرکز بر بهبود عملکرد، ساده‌سازی توسعه و ارتقاء تجربه کاربری، یه قدم بزرگ به سمت آینده‌ای مدرن‌تر و کارآمدتر برداشته.برای نصب نسخه بتا یا RC انگولار ۲۰، می‌تونید از دستور زیر استفاده کنید:npm install @angular/cli@nextng new angular-20-democd angular-20-demonpm install @angular/core@nextآخرش در فایل main.ts، برای فعال‌سازی حالت بدون Zone.js، خط مربوط به zone.js رو حذف کنید.با این تغییرات، می‌تونید از قابلیت‌های جدید انگولار ۲۰ بهره‌مند بشید و تجربه توسعه بهتری داشته باشید.امیدوارم از این مقاله لذت ببرید و براتون مفید باشه.اگر دوست دارید میتونید از طریق صفحه لینکدین با من در ارتباط باشید :)موفق باشید :)</description>
                <category>رهام رفیعی تهرانی</category>
                <author>رهام رفیعی تهرانی</author>
                <pubDate>Sat, 31 May 2025 09:49:09 +0330</pubDate>
            </item>
                    <item>
                <title>همه چی درباره‌ی Epic، Story و Task</title>
                <link>https://virgool.io/@roham.tehrani/%D9%87%D9%85%D9%87-%DA%86%DB%8C-%D8%AF%D8%B1%D8%A8%D8%A7%D8%B1%D9%87-%DB%8C-epic-story-%D9%88-task-%D8%AF%D8%B1-srcrum-spxb0szmbaxm</link>
                <description>اگه با جیرا یا ابزار های مشابه کار کرده باشی و پروژه‌هات رو با اسکرام یا کانبان پیش برده باشی، احتمال زیاد با سه‌ تا اسم برخورد کردی: Epic، Story و Task. حالا سوالی که همیشه پیش میاد اینه که اینا چی‌ان؟ چه فرقی با هم دارن؟ کِی باید از کدوم استفاده کنیم؟فرض کن یه نفر قراره یه سیستم بزرگ طراحی کنه. اون کسی که ایده داره و می‌دونه چی می‌خواد، بهش می‌گن Product Owner. اما اون که قراره کد بزنه و پیاده کنه، توسعه‌دهنده‌ست. این وسط باید یه جوری ارتباط برقرار شه.اینجاست که «User Story» وارد می‌شه. یه جور جمله‌ست که می‌گه: «به عنوان فلان نقش، می‌خوام فلان کار رو بکنم، تا به فلان نتیجه برسم.» همین! هیچ حرفی از کد یا دیتابیس یا تکنولوژی نیست.ولی بعضی وقتا این داستان‌ها خیلی بزرگ‌ می‌شن. اون‌ قدر که دیگه نمی‌شه گفت یه داستانه. باید بشکنیش به تیکه‌های کوچک‌تر. اون داستان بزرگ اسمش می‌شه Epic.مثال بزنم: می‌خوای یه سایت آموزشی مثل یودمی بسازی؟ خب یه Epic می‌تونه «مدیریت دوره‌ها» باشه. توی این Epic، چندین Story هست مثل ساخت دوره، ویرایشش، گذاشتن قیمت و غیره.حالا Story هم که گفتیم، داستان کاربره. ولی وقتی میری توی برنامه‌ریزی Sprint، تیم توسعه میاد می‌گه خب برای پیاده کردن این Story، باید فلان کار و فلان کار انجام شه. این کارای کوچیک‌تر می‌شن Task.در واقع Task همون چیزیه که یه برنامه‌نویس یا متخصص DevOps یا QA باید انجام بده تا اون Story واقعاً کامل شه.پس چی شد؟مفهوم Epic: یه داستان بزرگ که از چند تا Story کوچیک‌تر تشکیل شدهمفهوم Story: خواسته‌ی کاربر، بدون حرف فنیمفهوم Task: کارای ریز و واقعی که باید انجام بشه تا اون Story به نتیجه برسهامیدوارم از این مقاله لذت ببرید و براتون مفید باشه.اگر دوست دارید میتونید از طریق صفحه لینکدین با من در ارتباط باشید :)موفق باشید :)</description>
                <category>رهام رفیعی تهرانی</category>
                <author>رهام رفیعی تهرانی</author>
                <pubDate>Wed, 28 May 2025 10:25:20 +0330</pubDate>
            </item>
                    <item>
                <title>سوگیری های ذهنی</title>
                <link>https://virgool.io/@roham.tehrani/%D8%B3%D9%88%DA%AF%DB%8C%D8%B1%DB%8C-%D9%87%D8%A7%DB%8C-%D8%B0%D9%87%D9%86%DB%8C-wgtpau0gj6td</link>
                <description>یک مقاله ای رو چند وقت پیش در مورد سوگیری های ذهنی مطالعه کردم و خیلی خوشم اومد. اصلش در مورد مدیریت محصول بود ولی احساس کردم به کار ما برنامه نویس ها هم میاد. ترجمه ش کردم که تو محتوای فارسی هم باشه و شما هم استفاده کنین.آیا تا به حال پیش اومده که یقین داشته باشید فیچر جدیدی که طراحی کردید یا توسعه دادید دقیقاً همون چیزیه که کاربران بهش نیاز دارند، اما بعداً متوجه بشید اون قدرها هم مهم نبوده؟ همه ما موقع تصمیم‌گیری ممکنه دچار پیش‌داوری بشیم، حتی بهترین آدم ها هم ممکنه دچار پیش داوری بشن.ما آدم ها خیلی مواقع به غرایز و تجربیات‌مون تکیه می‌کنیم. اما یک نکته‌ای وجود داره: ذهن ما گاهی بازی‌مون میده و باعث بروز سوگیری‌هایی میشه که تصمیمات ما را به‌طور نامحسوس تحت تأثیر قرار میده. بیاید چند مورد رو مرور کنیم که بیشتر از بقیه اتفاق می افتند:سوگیری تأییدی (Confirmation Bias)انسان‌ها ذاتا تمایل دارند اطلاعاتی رو جست‌وجو کنند که باورهای فعلی‌شان رو تأیید کنه. مثلا این ممکنه به معنای تمرکز بر بازخوردهایی باشه که ایده‌های ما رو تأیید می‌کنن و نادیده گرفتن داده‌های متناقض. خطرش؟ ممکنه فیچرهایی بسازیم که فکر می‌کنیم درست هستند، نه چیزی که واقعاً کاربران نیاز دارند.سوگیری لنگر انداختن (Anchoring ‌Bios)وقتی بیش از حد به اولین اطلاعاتی که دریافت می‌کنیم تکیه می‌کنیم، این سوگیری شکل می‌گیره. مثلاً اگر اولین تست کاربری نشون بده یک فیچر خیلی مهمه، ممکنه اون رو بیش از حد در اولویت قرار بدیم، حتی اگر داده‌های بعدی خلافش رو نشون بده.سوگیری در دسترس بودن (Availability Heuristic)ما معمولاً اهمیت اطلاعاتی که به‌راحتی در دسترس یا تازه هستند رو بیش از حد تخمین می‌زنیم. اگر یک مشکل یا درخواست فیچر به تازگی مطرح شده باشه، ممکنه در برنامه‌ریزی بیش از حد بهش بها بدهیم.اثر موج همراهی (Bandwagon Effect)پیروی از جمع کار ساده‌ایه. اگر همه از یک روند یا فیچر خاص حمایت کنند، ممکنه ما هم بدون بررسی تطابق اون فیچر با اهداف محصول یا نیاز کاربران، دنباله‌رو بقیه بشیم.راهکارهایی برای مقابله با سوگیری‌ها۱. تنوع دیدگاه‌ها: از افراد با پیش‌زمینه‌های مختلف در تیم مون استفاده کنیم. دیدگاه‌های متفاوت اونها می‌تونه تصمیم‌گیری ما رو به چالش بکشه و غنی تر کنه.۲. تصمیم‌گیری مبتنی بر داده: به داده‌ها تکیه کنیم. از تحلیل رفتار کاربران و تحقیقات بازار برای انتخاب‌های آگاهانه بهره بگیریم، نه فقط حس شهودی.۳. بازخورد مستمر: به‌طور مداوم از کاربران و اعضای تیم بازخورد بگیریم. این کار کمک می‌کنه نقاط تاریک در درک مون رو شناسایی و رفع کنیم.۴. به چالش کشیدن فرضیات: همیشه از خودمون بپرسیم: «اگر اشتباه کرده باشیم چی؟» این طرز فکر فرهنگ تفکر انتقادی و شفافیت رو تقویت می‌کنه.۵. به‌روز ماندن: مدام درباره روندها و بینش‌های رفتاری جدید یاد بگیریم. آگاهی به‌روز به شناسایی و کنترل سوگیری‌ها کمک می‌کنه.نتیجهآگاهی از سوگیری‌های ذهنی و مدیریت آن‌ها بسیار حیاتیه. این فقط درباره تصمیم‌گیری بهتر نیست، بلکه درباره ساخت و توسعه محصولاتیه که واقعاً با طیف متنوع کاربران ارتباط برقرار می‌کنند.اولین قدم برای غلبه بر سوگیری‌ها، پذیرش اون هاست. بهتره همیشه در حال یادگیری، تطبیق و رشد باشیم.امیدوارم از این مقاله لذت ببرید و براتون مفید باشه.اگر دوست دارید میتونید از طریق صفحه لینکدین با من در ارتباط باشید :)اصل مقاله رو میتونید از اینجا مطالعه کنینموفق باشید :)</description>
                <category>رهام رفیعی تهرانی</category>
                <author>رهام رفیعی تهرانی</author>
                <pubDate>Tue, 20 May 2025 20:36:02 +0330</pubDate>
            </item>
                    <item>
                <title>آشنایی کامل با Core Web Vitals</title>
                <link>https://virgool.io/@roham.tehrani/%D8%A2%D8%B4%D9%86%D8%A7%DB%8C%DB%8C-%DA%A9%D8%A7%D9%85%D9%84-%D8%A8%D8%A7-core-web-vitals-fard3lao2jxl</link>
                <description>مقدمهدر دنیای رقابتی امروز، سرعت و کیفیت بارگذاری وب‌سایت‌ها نقش اساسی در جذب و حفظ کاربران دارند. گوگل با معرفی مجموعه‌ای از شاخص‌های کلیدی تحت عنوان Core Web Vitals، به مدیران وب‌سایت‌ها ابزاری داده تا عملکرد وب‌سایت خود را از نظر تجربه کاربری بسنجند و بهبود دهند. در این مقاله به معرفی Core Web Vitals، اهمیت آن‌ها در سئو و نحوه بهینه‌سازی هر یک از این شاخص‌ها می‌پردازیم.بحث Core Web Vitals چیست؟در واقع Core Web Vitals مجموعه‌ای از شاخص‌های عملکردی است که توسط گوگل معرفی شده‌اند و بر تجربه کاربر در تعامل با صفحات وب تمرکز دارند. این شاخص‌ها از سال 2021 به عنوان یکی از فاکتورهای رتبه‌بندی گوگل در نظر گرفته شده‌اند.سه معیار اصلی Core Web Vitals عبارت‌اند از:• Largest Contentful Paint (LCP)• First Input Delay (FID)• Cumulative Layout Shift (CLS)(در نسخه‌های جدید، گوگل معیار FID را با INP جایگزین کرده است که در ادامه توضیح داده می‌شود.)معیار Largest Contentful Paint (LCP) - بزرگ‌ترین زمان بارگذاری محتوامعیار LCP نشان می‌دهد که بارگذاری بزرگ‌ترین عنصر محتوایی قابل مشاهده (مانند تصویر یا بلوک متنی) چقدر طول می‌کشد. این شاخص مستقیماً با سرعت درک اولیه صفحه توسط کاربر مرتبط است.• مقدار مناسب: کمتر از 2.5 ثانیهروش‌های بهینه‌سازی:• استفاده از هاستینگ سریع‌تر• بهینه‌سازی تصاویر و فایل‌های CSS• استفاده از بارگذاری تنبل (Lazy Loading)معیار First Input Delay (FID) - تأخیر اولین تعامل کاربر (در حال جایگزینی با INP)معیار FID زمان تأخیر بین اولین تعامل کاربر با صفحه (مثلاً کلیک روی دکمه) و پاسخ مرورگر به آن را اندازه‌گیری می‌کند. این معیار برای سنجش تعامل‌پذیری صفحه به‌کار می‌رود.• مقدار مناسب: کمتر از 100 میلی‌ثانیهروش‌های بهینه‌سازی:• کاهش حجم جاوااسکریپت• تقسیم‌بندی کدها (Code Splitting)• استفاده از Web Workersنکته: گوگل از سال 2024 شروع به جایگزینی FID با Interaction to Next Paint (INP) کرده است که تعامل‌های واقعی‌تری را در طول استفاده کاربر اندازه می‌گیرد.معیار Cumulative Layout Shift (CLS) - جابه‌جایی چیدمان تجمعیمعیار CLS میزان پایداری عناصر در صفحه را اندازه‌گیری می‌کند. اگر در هنگام بارگذاری، عناصر صفحه بدون اطلاع جابجا شوند، امتیاز CLS بالا می‌رود که نشان‌دهنده تجربه کاربری بد است.• مقدار مناسب: کمتر از 0.1روش‌های بهینه‌سازی:• مشخص کردن ابعاد تصاویر و ویدیوها• اجتناب از بارگذاری عناصر پویا بدون اطلاع کاربر• استفاده از فونت‌های بهینه‌سازی شدهاهمیت Core Web Vitals در سئواز ژوئن 2021، Core Web Vitals به‌عنوان بخشی از الگوریتم رتبه‌بندی گوگل شناخته می‌شود. این بدان معناست که:• وب‌سایت‌هایی که نمره خوبی در این معیارها دارند، شانس بیشتری برای قرار گرفتن در رتبه‌های بالاتر دارند.• تجربه کاربری بهتر باعث افزایش نرخ تبدیل، کاهش نرخ پرش و افزایش تعامل کاربران می‌شود.ابزارهای اندازه‌گیری Core Web Vitalsبرای بررسی این شاخص‌ها می‌توانید از ابزارهای زیر استفاده کنید:• Google PageSpeed Insights• Lighthouse• Chrome DevTools• Web Vitals Chrome Extension• Google Search Console (گزارش Core Web Vitals)جمع‌بندیتعاریف Core Web Vitals یک بخش ضروری از بهینه‌سازی تجربه کاربری و سئو مدرن هستند. با درک درست این معیارها و اجرای بهینه‌سازی‌های لازم، می‌توانید رتبه سایت خود را در نتایج جستجو ارتقا دهید و رضایت کاربران را افزایش دهید. این سه معیار – LCP، FID/INP و CLS – ابزاری هستند که باید در کنار سایر فاکتورهای سئو در اولویت قرار گیرند.امیدوارم از این مقاله لذت ببرید و براتون مفید باشه.اگر دوست دارید میتونید از طریق صفحه لینکدین با من در ارتباط باشید :)موفق باشید :)</description>
                <category>رهام رفیعی تهرانی</category>
                <author>رهام رفیعی تهرانی</author>
                <pubDate>Tue, 13 May 2025 20:19:48 +0330</pubDate>
            </item>
                    <item>
                <title>اصطلاح banana in the box در انگولار</title>
                <link>https://virgool.io/@roham.tehrani/%D8%A7%D8%B5%D8%B7%D9%84%D8%A7%D8%AD-banana-in-the-box-%D8%AF%D8%B1-%D8%A7%D9%86%DA%AF%D9%88%D9%84%D8%A7%D8%B1-ln5mc9bj5erb</link>
                <description>امروز با یک اصطلاح جالبی آشنا شدم که بارها و بارها دیده بودم و خودم درگیرش بودم ولی نمیدونستم براش اصطلاح خلاصه ای وجود داره.اسم اصطلاح هست banana in the box و مربوط به syntax در two-way binding انگولار هست و در داکیومنت جدید انگولار هم به عنوان اصطلاح غیررسمی در جامعه انگولار بهش اشاره شده.روش two-way binding در انگولار به صورت رسمی این شکلی هست:[(ngModel)]=”model”مثلا در یک کامپوننت سفارشی بنام my-input میتونیم از این روش استفاده کنیم:&lt;app-custom-input [(value)]=”value”&gt;&lt;/app-custom-input&gt;در واقع این روش خلاصه نوشتن و خوانده مقدار model به صورت مجزا از هم هست:&lt;app-custom-input [text]=&quot;val&quot; (textChange)=&quot;val=$event&quot;&gt;&lt;/app-custom-input&gt;نمونه کامپوننت سفارشی مون میتونه به صورت زیر باشه:به این syntax خلاصه شده [()] میگن banana in the box .در واقع به [] میگن باکس و به () میگن موزامیدوارم از این مقاله لذت ببرید و براتون مفید باشه.اگر دوست دارید میتونید از طریق صفحه لینکدین با من در ارتباط باشید :)موفق باشید :)</description>
                <category>رهام رفیعی تهرانی</category>
                <author>رهام رفیعی تهرانی</author>
                <pubDate>Sun, 20 Apr 2025 11:13:34 +0330</pubDate>
            </item>
                    <item>
                <title>آشنایی با رنگ های ANSI در جاوااسکریپت</title>
                <link>https://virgool.io/@roham.tehrani/%D8%A2%D8%B4%D9%86%D8%A7%DB%8C%DB%8C-%D8%A8%D8%A7-%D8%B1%D9%86%DA%AF-%D9%87%D8%A7%DB%8C-ansi-%D8%AF%D8%B1-%D8%AC%D8%A7%D9%88%D8%A7%D8%A7%D8%B3%DA%A9%D8%B1%DB%8C%D9%BE%D8%AA-aylnhakdgedm</link>
                <description>دیروز با موضوعی آشنا شدم به اسم ANSI Colors یا رنگ های ANSI که برام جالب بود. این مقاله رو نوشتم که شما هم آشنا بشین.در جاوااسکریپت وقتی میخوایم متنی رو داخل کنسول بنویسیم از دستور console.log استفاده می‌کنیم.console.log(&amp;quotI&#039;m just the default text :(&amp;quot);و نتیجه ای که می‌بینیم یک متن سیاه روی بک گراند سفیدهاما به لطف چیزی به اسم ANSI escape sequesnces ما میتونیم کنترل بیشتری روی خروجی داشته باشیم و مشخص کنیم چطوری دیده بشه.در واقع ANSI escape sequesnces یک مجموعه از کدهای استاندارد هستند که به برنامه نویس اجازه میدن که به خروجی کنسول یا برنامه های متن پایه ( text based ) استایل بده. استفاده از این ANSI requences خیلی راحت و بانمکه.این مجموعه کدهای استاندارد باید با یک الگوی مشخص ( مجموعه کاراکترهای مشخص ) شروع میشن. به این الگو میگن escape code. در این مقاله از الگویی استفاده میکنیم که در همه زبان های رایج برنامه نویسی مثل جاوااسکریپت (Javascript)، پایتون (Python) و جاوا (Java) پشتیبانی میشه.\u001bبریم اولین نمونه از این کدهای دستوری رو ببینیم:خروجی این چند خط رو با هم ببینیم:دقت کنین که همه متن ها شامل escape code و style code و متن اصلی هستند:\u001b[ + style code (XXm) + output textکد های رنگ ANSI یا همون ANSI Colorsدر ANSI هشت کد رنگ اصلی داریم :سیاه = 30قرمز = 31سبز = 32زرد = 33آبی = 34سرخابی = 35فیروزه ای = 36سفید = 37مثال زیر نمونه خوبی برای استفاده این کدهاست:const RED = &quot;\u001b[31m&quot;;const BLUE = &quot;\u001b[34m&quot;;console.log(RED + &quot;I&#x27;m red!&quot;);console.log(BLUE + &quot;Or am I blue?&quot;);کد رنگ های پس زمینه ( Background ):لیست کد رنگ های پس زمینه به شرح زیر هستند:پس زمینه سیاه = 40پس زمینه قرمز = 41پس زمینه سبز = 42پس زمینه زرد = 43پس زمینه آبی = 44پس زمینه سرخابی = 45پس زمینه فیروزه ای = 46پس زمینه سفید = 47کد رنگ های پس زمینه بین ; و m قرار میگیرند و میتونن با رنگ متن یا بدون رنگ متن تنظیم بشن.text color + ; + background color + m مثال های زیر نمونه های خوبی هستند:و نتیجه خروجی ها رو ببینید:کدهای رنگ RGB در ANSIکدهای رنگ اضافه با دو الگوی قابل استفاده هستند. الگوی اول کد رنگ و الگوی دوم RGB هست.الگوی اول با کد رنگ:برای رنگ متن از الگوی زیر استفاده میکنیم:&quot;\u001b[38;5;&lt;color code&gt;m + output text&quot;برای رنگ پس زمینه هم از الگوی زیر استفاده میکنیم:&quot;\u001b[48;5;&lt;color code&gt;m + output text&quot;عکس زیر لیست کد رنگ هاست:الگوی دوم الگوی RGB هست:برای رنگ متن از الگوی زیر استفاده میکنیم:&quot;\u001b[38;2;&lt;R code&gt;;&lt;G code&gt;;&lt;B code&gt;m + output text&quot;و برای رنگ پس زمین از الگوی زیر استفاده میکنیم:&quot;\u001b[48;2;&lt;R code&gt;;&lt;G code&gt;;&lt;B code&gt; + output text&quot;در بخش بعدی می‌بینیم که چطور از این الگوها استفاده میکنیم.استفاده از رنگ های مختلف در یک متنمیتونیم داخل یک متن از رنگ های مختلفی استفاده کنیم. به مثال زیر توجه کنین:نتیجه میشه خروجی زیر:ریست کردن رنگ تنظیم شدهبرای برگشتن رنگ متن به رنگ پیش فرض از کد زیر استفاده میکنیم:[0mنمونه استفاده ش رو در کد زیر نوشتم:و خروجی زیر رو میبینیم:نکته مهم: در جاوااسکریپت ، موقع اجرای هر console.log خود به خود همه چیز بر اساس رنگ پیش فرض اجرا میشه و نیازی به کد ریست نیست:const WHITE_CYAN = &quot;\u001b[37;46m&quot;;console.log(WHITE_CYAN + &quot;I am colorful&quot;);// Does not have the same color as above, even with no manual resetconsole.log(&quot;But I am not&quot;);ولی در پایتون کنسول خود به خود ریست نمیشه و باید حتما دستور ریست اجرا بشه:WHITE_CYAN = &quot;\u001b[37;46m&quot;print(WHITE_CYAN + &quot;I am colorful&quot;)# Has the same color as above, since it was not manually resetprint(&quot;And so am I&quot;)استایل های دیگرسه کد دیگر که به عنوان ANSI Decoration معروف هستند عبارتند از:Bold: \u001b[1mItalicized: \u001b[3mUnderline: \u001b[4mسخن آخرحتما این موارد رو آزمایش کنید و خروجی بگیرید تا بیشتر به یادتون بمونه. من شخصا پکیج logger پروژه ام رو با این موارد آپدیت کردم.امیدوارم از این مقاله لذت ببرید و براتون مفید باشه.اگر دوست دارید میتونید از طریق صفحه لینکدین با من در ارتباط باشید :)متن مقاله اصلی رو میتونید اینجا مطالعه کنید.موفق باشید :)</description>
                <category>رهام رفیعی تهرانی</category>
                <author>رهام رفیعی تهرانی</author>
                <pubDate>Mon, 24 Mar 2025 19:16:56 +0330</pubDate>
            </item>
                    <item>
                <title>راه حل تعریف Path Alias در Jest</title>
                <link>https://virgool.io/@roham.tehrani/%D8%B1%D8%A7%D9%87-%D8%AD%D9%84-%D8%AA%D8%B9%D8%B1%DB%8C%D9%81-path-alias-%D8%AF%D8%B1-jest-v7ban5p2ewu7</link>
                <description>چند وقت یک پروژه Next رو تحویل گرفتم که توسعه ش بدم. یک خط کد تست براش نوشته نشده بود. منم کتابخونه Jest رو نصب کردم که شروع کنم روی پروژه تست بنویسم.به یک مشکل بزرگ رسیدم. Jest تنظیمات path aliases پروژه رو متوجه نمیشد. با توجه به تغییرات نسخه به نسخه ای که کرده، پیدا کردن راه حل برای نسخه های جدید یک کم طول کشید. برای همین تصمیم گرفتم یک مقاله درباره ش بنویسم.تنظیمات Path Alias در پروژهاول از همه ببنیم این تنظیمات داخل پروژه کجا انجام میشه.این تنظیمات به کامپایلر typescript مربوط میشه و بنابر این داخل فایل tsconfig.js نوشته میشه. داخل آبجکت compilerOptions و قسمت paths میتونیم تعریفشون کنیم:یا مثلا میتونه این جوری بشه:تنظیمات Path Alias در Jestدر NextJS با اولین اجرای دستور npm run test  به این خطا خوردم که import با حضور path alias رو متوجه نمیشه و خطا میده که این مسیر رو تشخیص نمیدم.در نسخه های جدید Next باید داخل فایل jest.config.js که با نصب کتابخونه Jest ساخته میشه ، path alias ها رو  در بخشی به عنوان moduleNameMapper تعریف کنیم:شاید چندین راه حل مختلف رو پیدا کردم که همگی قدیمی هستند و متاسفانه به خاطر بازدید بالا، جلوتر و بیشتر نمایش داده میشن. ولی بالاخره راه حل رو پیدا کردم.شبیه همین مقاله رو زمانی که انگولار کار میکردم به اسم آشنایی با Module Resolution در انگولار نوشتم.امیدوارم از این مقاله لذت ببرید و براتون مفید باشه.اگر دوست دارید میتونید از طریق صفحه لینکدین با من در ارتباط باشید :)اصل مقاله شامل پیاده سازی با جاوا هم هست. میتوانید مقاله اصلی رو اینجا مطالعه کنید.موفق باشید</description>
                <category>رهام رفیعی تهرانی</category>
                <author>رهام رفیعی تهرانی</author>
                <pubDate>Tue, 18 Mar 2025 15:04:08 +0330</pubDate>
            </item>
                    <item>
                <title>شمارش تعداد کاربران آنلاین در اپلیکیشن وب</title>
                <link>https://virgool.io/@roham.tehrani/%D8%B4%D9%85%D8%A7%D8%B1%D8%B4-%D8%AA%D8%B9%D8%AF%D8%A7%D8%AF-%DA%A9%D8%A7%D8%B1%D8%A8%D8%B1%D8%A7%D9%86-%D8%A2%D9%86%D9%84%D8%A7%DB%8C%D9%86-%D8%AF%D8%B1-%D8%A7%D9%BE%D9%84%DB%8C%DA%A9%DB%8C%D8%B4%D9%86-%D9%88%D8%A8-wlrdgaimsben</link>
                <description>توانایی ردیابی تعداد کاربران آنلاین در یک وب اپلیکیشن برای مسائلی مثل میزان استقبال کاربران، بهینه سازی سرورها از لحاظ بازدهی و حتی مسائل امنیتی بسیار مهم و حیاتی است.چه برای یک بلاگ کوچک چه برای یک پلتفرم عریض و طویل، دانستن تعداد کاربران آنلاین در هر لحظه، اطلاعات  ارزشمند و مهمی رو به همراه داره.در این مقاله میخوایم راه حل های مختلف شمارش کاربران آنلاین رو مرور کنیم.بخش اول : درک مفهوم کاربر آنلاینقبل از اینکه به راه حل های فنی بپردازیم، اول به درک مشترکی از مفهوم کاربر آنلاین برسیم.در وب اپلیکیشن ها، یک کاربر آنلاین به کسی گفته میشه که یک جلسه ( session ) فعال روی پلتفرم داره یا به تازگی تعاملی با سرور داشته. به کمک کوکی ها ، session ها و web socket ها میتونیم این تعاملات رو رصد کنیم.یک کاربر آنلاین در بیشتر اپلیکیشن های وب به کسی گفته میشه که اخیرا صفحه ای باز کرده، تعاملی با سرور داشته، یا فعالیتی انجام داده. برای تعریف اخیرا باید بازه زمانی در نظر بگیریم. مثلا از الان تا ۵ دقیقه قبل.در اپلیکیشن های در لحظه (real-time) ، به کمک web socket ها میتونیم کاربران آنلاین رو با به روز رسانی وضعیت شون شناسایی کنیم.هر روشی مزایا و معایب خودش رو داره که در ادامه بهش میپردازیم.راهکارهای عمومی دریابی کاربران آنلاین عبارتند از: ردیابی session-basedردیابی token-based ( مثل jwt )ردیابی WebSocketدیتابیس های in-memory مثل Redis برای به روز رسانی های real-timeبخش دوم :‌ ردیابی Session-Based راه حل معروف و مستقیم ردیابی کاربران آنلاین استفاده از طریق session است. در جاوا هنگام استفاده از Spring Boot شما میتوانید از HttpSession برای مدیریت جلسات و ردیابی کاربران استفاده کنید.بخش سوم: ردیابی Token-basedبا نگهداری توکن های active و زمان انتقضای آنها در مثلا Redis، شما میتوانید تعداد توکن های ولید را در هر لحظه داشته باشید.بخش چهارم: ردیابی WebSocketبه ازای هر کاربر شما میتوانید یک ارتباط WebSocket بین کلاینت و سرور برقرار کنید. به محض قطع ارتباط، session ارتباطی حذف میشود. با شمارش تعداد ارتباطات فعال میتوانید کاربران در لحظه را شمارش کنید.امیدوارم از این مقاله لذت ببرید و براتون مفید باشه.اگر دوست دارید میتونید از طریق صفحه لینکدین با من در ارتباط باشید :)اصل مقاله شامل پیاده سازی با جاوا هم هست. میتوانید مقاله اصلی رو اینجا مطالعه کنید.موفق باشید</description>
                <category>رهام رفیعی تهرانی</category>
                <author>رهام رفیعی تهرانی</author>
                <pubDate>Sun, 16 Mar 2025 15:36:15 +0330</pubDate>
            </item>
                    <item>
                <title>زوم دو انگشتی در nextJS یا pinch zoom</title>
                <link>https://virgool.io/@roham.tehrani/%D8%B2%D9%88%D9%85-%D8%AF%D9%88-%D8%A7%D9%86%DA%AF%D8%B4%D8%AA%DB%8C-%D8%AF%D8%B1-nextjs-%DB%8C%D8%A7-pinch-zoom-owwrt0ptdsao</link>
                <description>هر چند سالی که در یک حوزه کار کنی، باز هم ممکنه موردی پیش بیاد که تا حالا باهاش برخورد نداشتی. به نظرم هر چقدر هم که این چالش کوچک یا بزرگ باشه، در هر حرفه و تخصصی خیلی جذابه.چند وقت پیش یک فیچری مطرح شد در اپ در حال توسعه مون. چی بود؟ قابلیت زوم دو انگشتی روی یک عکس که بشه روی عکس zoom in یا zoom out کرد.من هم از بین همه کارها روی این موضوع زوم کردم و برش داشتم. چون تا قبلش صرفا با event های touch آشنا بودم و مدل های دیگه ای از این event رو پیاده سازی کردم بودم. ولی این فیچر رو پیاده نکرده بودم.گفتم این فیچر رو با شما هم مطرح کنم، اگر برخورد نکردین حداقل چشم تون یه بار دیده باشه.این فیچر رو با تغییر نحوه نگه داشتن متغیرها و فراخوان event ها، میتونید در جاوااسکریپت vanilla هم استفاده کنید یا حتی فریم ورک محبوب من انگولار.لیست event هایی که لازم داریم:اولیش touchStartدومیش touchMoveسومیش touchEndوقتی که ما آبجکت مورد نظر در صفحه رو لمس میکنیم، ایونت touchStart فعال میشه. مادامی که دستمون رو روی صفحه حرکت میدیم، به صورت رگباری event های touchMove فعال میشن. در انتها که دستمون رو برمیداریم ایونت touchEnd فراخوانی میشه.این ایونت ها به این صورت صدا زده میشن:اگر به داخل آبجکت ایونت touchStart و touchMove نگاه کنیم، دو تا متغیر می بینیم که خیلی به کار ما میاد:touchestargetTouchesمتغیر targetTouches یک لیسته که اندازه ش برابره با تعداد انگشت های کاربر که همزمان صفحه رو تاچ میکنند. یعنی برای اینکه ببینیم دو انگشتی تاچ صورت گرفته یا نه، از کد زیر استفاده میکنیم:متغیر touches هم یک لیست از آبجکت هاییه که مختصات نقطه تاچ رو به ما میدهما اگر بتونیم فاصله بین دو نقطه تاچ رو در touchStart رو اندازه گیری کنیم و در یک متغیر نگه داریم،بعد فاصله بین دو نقطه تاچ در touchMove رو اندازه گیری کنیم و در یک متغیر دیگه دائم آپدیت کنیم،بعد در touchEnd این دو فاصله رو مقایسه کنیم،میتونیم بفهمیم که دو انگشت از هم دورتر  شدند یا نزدیک‌تر. اگر دورتر شده بودند zoom out کنیم و اگر نزدیک تر شدند zoom in کنیم.پس اول دو تا متغیر در کامپوننت nextjs تعریف میکنم. اولی برای نگه داشتن فاصله بین دو نقطه تاچ در touchStart و دومی برای نگه داشتن فاصله بین دو نقطه تاچ در touchMove:اگر مثلثات یادتون مونده باشه، میدونید که در مثلث قائم الزاویه، اندازه ضلع بزرگتر رو چطور به دست میارن:حالا فرض کنید دو طرف ضلع z در واقع دو نقطه تاچ ما هستند. مقدار x در واقع اختلاف pageY های دو نقطه تاچ و مقدار Y در واقع اختلاف pageX های دو نقطه تاچ ما هستند. معادلش بر اساس مقادیری که از طریق  event به ما منتقل میشه، کد پایینه:یه نکته دیگه از ریاضیات هم هست. وقتی یک عدد رو به توان دو میرسونیم، چه منفی باشه چه مثبت جواب یکیه. یعنی مقدار x به توان ۲ با -x به توان ۲ فرقی نداره. در واقع نیازی نیست که حتما ورودی ما مقدار مثبت باشه. میتونه منفی همون عدد هم باشه.من نمیدونستم ( یا خواندم ولی یادم رفته ) که جاوااسکریپت در کتابخانه Math ، همچین تابعی داره بنام hypot. مقدار Y و X رو ورودی می‌گیره و مقدار Z برمیگردونه. پس فاصله بین دو نقطه تاچ رو در ایونت های touchStart و touchMove با کد زیر به دست میاریم:این تابع از ۲۰۱۵ در مرورگرها پشتیبانی میشه. میتونیم مستقیما از Math.sqrt هم استفاده کنیم که قدیمی تره:در انتها ( ایونت touchEnd ) هم این دو مقدار رو مقایسه میکنیم و متوجه میشیم zoom in کردیم یا zoom outالگوریتم zoom in و zoom out رو جدا پیاده سازی کنید که از طرق دیگه هم بتونید پیاده سازیش کنین. مثلا با کلیک رو دکمه های zoom in , zoom out هم کاربر بتونه کار کنه.امیدوارم از این مقاله لذت ببرید و براتون مفید باشه.اگر دوست دارید میتونید از طریق صفحه لینکدین با من در ارتباط باشید :)موفق باشید</description>
                <category>رهام رفیعی تهرانی</category>
                <author>رهام رفیعی تهرانی</author>
                <pubDate>Tue, 17 Sep 2024 14:28:40 +0330</pubDate>
            </item>
                    <item>
                <title>در اپ انگولار از Signal استفاده کنیم یا RxJS ؟</title>
                <link>https://virgool.io/@roham.tehrani/%D8%AF%D8%B1-%D8%A7%D9%BE-%D8%A7%D9%86%DA%AF%D9%88%D9%84%D8%A7%D8%B1-%D8%A7%D8%B2-signal-%D8%A7%D8%B3%D8%AA%D9%81%D8%A7%D8%AF%D9%87-%DA%A9%D9%86%DB%8C%D9%85-%DB%8C%D8%A7-rxjs-ipng1bvnkqsf</link>
                <description>چند ماهی هست که تمرکزم روی NextJs هست . هفته اخیر اما برای پشتیبانی اپ انگولار وقت گذاشتم و یه کم به حال و هوای انگولار برگشتم. طی همین هفته یک مقاله در حوزه انگولار خواندم و حس کردم محتوای مفیدی ارائه داده و با تجربه های من هم خیلی سازگاره. تصمیم گرفتم همینجوری دلی به فارسی ترجمه ش کنم و اینجا با شما به اشتراک بگذارم.این مقاله مقایسه کاملی از کتابخانه های Signal (کتابخانه جدید) و RxJS (کتابخانه قدرتمند قدیمی) ارائه داده و کمک میکنه که توسعه دهنده انگولار بتونه تا با قدرت و تسلط بیشتری تصمیم بگیره که بین کتابخانه های Signal و RxJS کدوم رو انتخاب کنه.در این مقاله چکیده نقاط ضعف و قدرت و موارد استفاده هر کتابخانه بررسی میشه.کتابخانه RxJSکتابخانه RxJS سالها سنگ بنای مدیریت جریان دیتا (data stream) در اپلیکیشن های انگولار بوده. این کتابخانه دیتاهای Asynchronous رو مدیریت میکنه.یه نگاهی به نقاط قوت RxJS بندازیم:مجموعه ابزارهای کامل و متنوعی رو برای مدیریت جریان داده های پیچیده ارائه میدهبرای دیتاهای Asynchronous عالیهبرای مدیریت event ها عالیهامکان کنسل کردن subscription دارهنقاط ضعف کتابخانه RxJS عبارتند از:نیاز به یادگیری زیاد و عمیق دارهاگر subscription ها درست مدیریت نشوند، ممکنه باعث memory leak بشهبرای سناریوهای ساده بیش از حد توانمندهبهترین ابزاره برای:ریکوئست های httpمدیریت event های پیچیدهترکیب کردن جریان های دیتاکتابخانه Angular Signalابزار سیگنال در واقع یک wrapper هست دور یک مقدار (value) که تغییرات اون مقدار رو به اطلاع مصرف کننده ها (consumers) میرسونه. این ابزار هر نوع مقداری رو پشتیبانی میکنه ، از مقادیر primitive تا آبجکت های پیچیده.نقاط قوت Angular Signal:سادگی در پیاده سازی و مدل سازیبازدهی عالی در دیتاهای Synchronousامکان ادغام با change detection سنتی انگولارکاهش پیچیدگی ها و مشکلات عجیبنقاط ضعف Angular Signal:مجموعه امکانات کم نسبت به کتابخانه RxJSاز پایه برای دیتاهای Synchronous طراحی شدهجدیدتره و اکوسیستمش در حال توسعه استبهترین ابزاره برای:مدیریت وضعیت دیتاهای در سطح کامپوننتکنترل دیتاهای جانبی یا نتایج محاسباتاپلیکیشن هایی که سرعت عمل بسیار بالایی نیاز دارندتولید کد ساده و خوانا بدون پیچیدگی خاصیبرای همین بهتره:از Angular Signal برای مدیریت دیتاهای سطح کامپوننت استفاده کنیماز RxJS برای مدیریت ریکوئست ها ، event ها و دیتاهای Asynchronousامکانات toSignal و toObservable برای ادغام این دو ابزار قدرتمندمیشه از این دو تا ابزار قدرتمند در کارهای مربوط به خودشون استفاده کرد و به وقتش اون ها رو با هم ترکیب کرد. در واقع میتونیم ترکیبی از سادگی زیاد، عملکرد قوی و پیچیدگی مدیریت Asynchronous رو پیاده کنیم.مثال زیر نمونه خوبیه:شناسه کاربر (userId) یک دیتای سطح کامپوننته که تغییرش باعث ارسال ریکوئست به سرور و دریافت اطلاعات اون کاربر میشه. بنابر این مقدارش با یک سیگنال wrap میشه.ابزار toSignal به ما امکان میده که مقدار خروجی یک Observable رو با یک سیگنال wrap کنیم. پس ما نتیجه ریکوئست دریافت اطلاعات کاربر رو در یک سیگنال بنام userSignal نگه میداریم.در واقع اطلاعات کاربر به صورت یک متغیر در سطح کامپوننت نگه داشته میشه.یک دیتای جانبی هم نیاز داریم که تعداد پست های کاربر رو شامل میشه (postCount). بهترین ابزار برای نگهداری دیتاهای جانبی سیگناله. به محض تغییر دیتای اصلی، دیتای جانبی رو آپدیت میکنه و در اختیار مصرف کننده ها قرار میدهبنابر این با صدا کردن تابع updateUser و در صورت تغییر userId:مقدار userId در سطح کامپوننت تغییر میکنه.ریکوئست برای اطلاعات کاربر جدید ارسال میشهننتیجه ش در یک signal بنام userSignal در سطح کامپوننت نگه داشته میشهبا تغییر userSignal ، دیتای جانبی postCount در کامپوننت تغییر میکنهنتیجه نهاییهمین طور که انگولار تکامل پیدا میکنه، درک عمیق این دو ابزار قدرتمند و استفاده درست ازشون میتونه منجر به تولید اپلیکیشن هایی بشه که سریع تر، سبک تر و پایدارتر رفتار میکنند.مقاله های مرتبط:آشنایی با انگولار سیگنال ، فیچر جذاب نسخه ۱۶انواع Subject در RxJSآشنایی با کتابخانه RxJSامیدوارم از این مقاله لذت ببرید و براتون مفید باشه.اگر دوست دارید میتونید از طریق صفحه لینکدین با من در ارتباط باشید :)لینک اصلی مقالهموفق باشید</description>
                <category>رهام رفیعی تهرانی</category>
                <author>رهام رفیعی تهرانی</author>
                <pubDate>Sat, 17 Aug 2024 12:23:46 +0330</pubDate>
            </item>
                    <item>
                <title>تنظیم نحوه ارسال آرایه به سرور در axios</title>
                <link>https://virgool.io/@roham.tehrani/%D8%AA%D9%86%D8%B8%DB%8C%D9%85-%D9%86%D8%AD%D9%88%D9%87-%D8%A7%D8%B1%D8%B3%D8%A7%D9%84-%D8%A2%D8%B1%D8%A7%DB%8C%D9%87-%D8%A8%D9%87-%D8%B3%D8%B1%D9%88%D8%B1-%D8%AF%D8%B1-axios-bwu2nbvgdig3</link>
                <description>چند وقت پیش یک api دستم رسید که باید در یک فیلد خاص، آرایه ای از شناسه ها رو به سمت سرور ارسال میکردم. ارسال request با axios انجام میشد ولی من تجربه کار با axios رو نداشتم. برای هماهنگ شدن کارکرد فرانت و بک مجبور شدم نیم ساعتی سرچ کنم تا به نتیجه مطمئن برسم. در این مقاله میخوام در مورد اون سرچ ساده صحبت کنم.صورت مسئلهفرض کنید یه آرایه از شناسه ها داریمconst arr=[2,3,4]قراره این شناسه ها با پارامتری بنام ids ، در ریکوئستی با متد GET ، از سمت فرانت به بک اند ارسال بشه.در مدلی که سمت بک اند پیاده سازی شده بود، انتظار میرفت آرایه ها به صورت زیر ارسال بشه:/api/something?ids=2&amp;ids=3&amp;ids=4در حالیکه به صورت پیش فرض از سمت فرانت به صورت زیر ارسال میشد:/api/something?ids[]=2&amp;ids[]=3&amp;ids[]=4توضیح کلیبه صورت کلی آرایه ای از مقادیر که به صورت GET و داخل url قراره ارسال بشه سه حالت استاندارد داره۱. حالت بدون براکت []ids=2&amp;ids=3&amp;ids=4۲. حالت با براکت بدون indexids[]=2&amp;ids[]=3&amp;ids[]=4۳. حالت با براکت و با indexids[0]=2&amp;ids[1]=3&amp;ids[2]=4یک حالت غیراستاندارد هم هست که پیشنهاد میکنم ازش اجتناب کنیدids=2,3,4با خودم فکر کردم من دارم از یک کتابخانه استاندارد، قدیمی (تکمیل شده) به غایت پرطرفدار استفاده میکنم بنام axios. بنابر این احتمالش خیلی زیاده که توسعه دهندگانش برای پشیبانی کردن از این سه حالت راه حلی ارائه داده باشند.بعد از سه چهار تا سرچ و اصلاح keyword بالاخره به جواب مورد نظرم رسیدمکتابخانه axios در پارامترهای ارسال ریکوئست خودش یک تنظیمی داره بنام paramsSerializer. داخل این تنظیم یک پراپرتی هست بنام indexes که سه تا مقدار میگیره برای سه حالت استانداردتنظیم حالت بدون براکتتنظیم حالت با براکت بدون indexتنظیم حالت با براکت با indexمقدار پیش فرض این تنظیم حالت false هست، یعنی ارسال آرایه مقادیر با براکت بدون index . بنابر این با تغییر تنظیمات axios موقع ساخت instance ، تونستم ارتباط صحیح با سرور رو برقرار کنم.امیدوارم از این مقاله لذت ببرید و براتون مفید باشه.اگر دوست دارید میتونید از طریق صفحه لینکدین با من در ارتباط باشید :)موفق باشید</description>
                <category>رهام رفیعی تهرانی</category>
                <author>رهام رفیعی تهرانی</author>
                <pubDate>Tue, 21 May 2024 21:27:08 +0330</pubDate>
            </item>
                    <item>
                <title>نمایش کامپوننت با theme های مختلف در React و NextJS</title>
                <link>https://virgool.io/@roham.tehrani/%D8%A7%D8%B6%D8%A7%D9%81%D9%87-%DA%A9%D8%B1%D8%AF%D9%86-theme-%D8%A8%D9%87-%DA%A9%D8%A7%D9%85%D9%BE%D9%88%D9%86%D9%86%D8%AA-%D8%AF%D8%B1-react-hxaps2ekuslf</link>
                <description>این چند وقته سرم حسابی شلوغه و کمتر میرسم مطالعه جانبی داشته باشم. اخیرا یک تجربه ای در حوزه NextJS داشتم که ارزش به اشتراک گذاشتن داره. اونم ارائه یک کامپوننت با چند تا تم مختلف هست. وقتی قراره به عنوان ورودی اسم یک تم رو بگیریم و بر اساس اون تم شرایط نمایش کامپوننت عوض بشه.تقریبا همه راه حل هایی که در سرچ پیدا کردم قدیمی شدند، واقعا به درد نمیخوردند و قابل پیاده سازی با TypeScript نبودند.در این روش در واقع همه چیز در abstraction مشخص میشه و داخل تابع کامپوننت فقط مقداردهی صورت میگیره.فاز اول: تعریف های abstractionفرض کنید یک کامپوننت دارم به است MyComponent که قراره با چند تا تم پیاده بشه و به عنوان ورودی یکی از تم ها رو بهش پاس بدیم.اول میام یک تایپ اضافه میکنم و متغیرهای هر تم رو مشخص میکنم:این متغیرها میتونن شامل آیکن ها یا هر رنگ و متن و عددی باشند.اگر شما هم مثل من از  tailwind  استفاده میکنین، حواستون به داینامیک کردن اسم کلاس ها در tailwind باشه.اگر لازمه مقاله داینامیک کردن اسم کلاس ها در tailwind رو مطالعه کنید.بعدش میام یک لیست از تم ها رو داخل کامپوننت مهیا میکنم:و در آخر با استفاده از keyOf type operator در typescript تایپ ورودی کامپوننت رو مشخص میکنم:فاز دوم: مقدار دهی هااول ورودی کامپوننت رو مشخص میکنماگر قبلا از این کامپوننت جاهای متعددی استفاده کردیم، میتونیم ورودی تم رو اختیاری تعریف کنیم. اگر ورودی مشخص نشه، از همون تمی استفاده میکنیم که قبلا استفاده میکردیم.مرحله دوم میام داخل کامپوننت مقدار دهی theme ها رو انجام میدم:اگر مثال اول مقاله رو ببینیم،  مشخصه که تم همیشگی مون dark هست.مرحله سوم defaultTheme و تم فعلی رو تعریف میکنم:کد بالا خوانایی بالاتری داره. کد پایین جمع و جور تره:مرحله آخر وقت تغییر خروجی کامپوننت هست:بریم کل کارهای انجام شده رو با هم ببینیم:فاز سوم: استفاده از قابلیت جدیدمیتونم به همون شکل سابق از کامپوننتم استفاده کنم:در این حالت همه چیز دقیقا مثل قبل نمایش داده میشه.یا با مشخص کردن یکی از تم ها:مشخص کنم کامپونتن با کدوم تم میخوام نمایش داده بشهموفق باشید</description>
                <category>رهام رفیعی تهرانی</category>
                <author>رهام رفیعی تهرانی</author>
                <pubDate>Sat, 11 May 2024 20:20:19 +0330</pubDate>
            </item>
            </channel>
</rss>