وبلاگها ، سایتها و مقالات ایرانی (داخل و خارج از ایران)
- مروری بر Delphi 2009 و مهاجرت به آن
- تصحیح خودکار کلمات فارسی در برنامه اپنآفیس
- دانلود عکس از سایت
- ۱۰ قانون برای نوشتن در وب
- استفاده از SQL Server در PHP
- بلوهاست و ایران
- سورس و گزارش پروژه فارسی نت منتشر شد
- درون یک ISP چه می گذرد؟
- تابعهای جادویی PHP 5
- راهنمای کوچک همکاری در پروژههای بازمتن
- nsis قدرتمندتر از آنچه یک نصب کننده نرم افزار نیاز دارد!
- چند اشتباه رایج در طراحی وب
امنیت
Visual Studio
ASP. Net
طراحی و توسعه وب
PHP
اسکیوال سرور
سی شارپ
VB
CPP
عمومی دات نت
مسایل اجتماعی و انسانی برنامه نویسی
- چه برنامهنویسهایی را استخدام نکنید؟
- چرا خانمها کمتر در پروژههای سورس باز ظاهر میشوند؟!
- IE6 را نمیخواهیم!
متفرقه
فرآیند داده کاوی در Microsoft SQL Server (بخش یک)
مقدمه
بطور کلی داده کاوی به دو قسمت زیر تقسیم میشود:
1- اهداف توصیفی (Descriptive Goal): بدنبال یافتن الگوها و روابط بین دادهها هستیم، بدین ترتیب مدلی برای توصیف بهتر دادهها بدست خواهد آمد.
2- اهداف پیش بینانه (Predictive Goal): بدنبال انجام پیش بینی با استفاده از الگوها و مدلهای فوق هستیم.
همچنین مراحل اجرای یک پروژه داده کاوی شامل مراحل زیر است:
1- تحلیل: مهمترین فعالیت در این فاز، فهم عمیق مسئله و شناخت درست مسئله و شناسائی مفاهیم کلیدی (Key Concept) در مسئله است.
2- طراحی: مهمترین فعالیت این فاز، فرموله کردن مسئله با استفاده از مفاهیم کلیدی است.
3- پیاده سازی/ نگهداری و بهبود
مراحل کاری داده کاوی بر اساس استاندارد CRISP-DM
محصول
مشترک شرکتهای SPSS, Teradata, NCR و دایملر- کرایسلر است و یک فرآیند
استاندارد Cross-Industry برای داده کاوی است که به طور گسترده ای استفاده
میشود. مراحل کاری در این مدل به شش فاز اصلی به شرح زیر تقسیم میشوند:
1. درک پروژه و فهم حوزه کاربرد (Business Understanding):
به طور صریح و آشکار اهداف و نیازمندیها مشخص میشود. ترجمه اهداف و
محدودیت آن در قاعده سازی، تعریف مسئله داده کاوی و مهیا کردن استراتژی
اولیه برای نائل شدن به اهداف در این مرحله تعریف می شود.
2. انتخاب دادهها (Data Understanding):
این مرحله شامل جمع آوری دادهها برای استفاده از تحلیل اکتشافی و مشخص
کردن اطلاعات اولیه برای ارزیابی دادههای با کیفیت و انتخاب دادههای
مفید و مورد نیاز میباشد.
3. آماده سازی دادهها (Data Preparation):
آماده کردن دادههای اولیه خام به دادههای نهایی، این دادها در کلیه
مراحل بعدی استفاده میشود و از این نظر این مرحله تحلیل و تلاش بیشتری را
میطلبد. انتخاب عناصر و شناسههای تحلیل شده را برای کاوش دادهها
اختصاص میدهیم و با تمیز کردن دادههای خام آن را برای ابزارهای مدل سازی
آماده می کنیم.
4. مدل سازی (Modeling):
با انتخاب و به کار بستن تکنیکهای مدل سازی مناسب و روش داده کاوی معین
نتایج مدل سازی را بهینه می کنیم، که در صورت نیاز میتوانیم با برگشت به
عقب تحلیل مدل سازی را بهینهتر نماییم.
5. ارزیابی (Evaluation):
مشخص کردن اینکه آیا مدل انتخابی، ما را به اهدافمان که در اولین مرحله
تعیین کردیم، می رساند. اتخاذ تصمیم راجع به استفاده از نتایج داده کاوی
برای اعتبارسنجی نیز در این مرحله انجام می شود.
6. استقرار (Deployment):
استفاده کردن از مدل ایجاد شده، برای مثال میتواند تولید یک گزارش ساده از
خروجیها را نام برد، و برای یک مثال پیچیده تکمیل کردن پردازش داده کاوی
موازی در سایر حوزهها میباشد، که این الگوها به یک دانش مفید و قابل
استفاده تبدیل میشوند و پس از بهبود آنها، الگوهایی که کارا محسوب می
شوند در یک سیستم اجرایی به کار گرفته خواهند شد.
مراحل کاری داده کاوی در بستر تکنولوژی Microsoft
داده کاوی غالباً به عنوان فرآیند استخراج اطلاعات، الگوها و روندهای موجود در مجموعه ی عظیمی از دادهها یاد می شود. این الگوها و روندها را می توان به عنوان یک مدل کاوشی تعریف نمود. به بیانی دیگر ایجاد یک مدل کاوشی بخشی از فرآیند بزرگتری است که در برگیرنده ی همه مراحل؛ از تعریف مسئله که مدل حل خواهد نمود تا اجرای مدل در محیطهای کاری است. می توان این فرآیند را با استفاده از 6 مرحله اساسی زیر تعریف نمود:
باید در نظر داشت که تهیه یک مدل داده کاوی، فرآیندی چرخشی، پویا و تکرار پذیر می باشد و ممکن است هر یک از این مراحل آن قدر تکرار شود، تا مدل مناسبی تهیه گردد.
- تعریف مسئله (Defining the Problem):
تعریف روشنی از مشکل و مسئله کسب و کار است. این مرحله شامل تجزیه و تحلیل نیازمندیهای کسب وکار، تعریف دامنه مشکل، تعریف معیارهایی که با آن مدلها ارزیابی خواهد شد و تعریف هدف نهایی پروژه ی داده کاوی است.
- آماده سازی دادهها (Preparing Data):
یکپارچه سازی و پالایش داده هایی است که در مرحله ی تعریف مسئله فرآیند معین شده است. SSIS حاوی تمامی ابزارهای ملزوم برای تکمیل این مرحله میباشد.
- بررسی دادهها (Exploring Data):
به منظور تصمیم گیریهای مناسب در هنگام تهیه مدل، می بایست دادهها را درک نمود و پس از آن می توان تصمیم گیری در مورد وجود دادههای مخدوش در مجموعه داده و در نهایت استراتژی مناسب برای رفع این مشکلات اتخاذ نمود. Data Source view Designer موجود در BIDS حاوی ابزارهای جامعی برای بررسی و شناخت دادهها شامل محاسبه ارقام حداقل و حداکثر، محاسبه میانگین و انحراف معیار و بررسی توزیع دادهها می باشد.
- تهیه مدل ها (Building Models):
پیش از تهیه مدل باید، دادهها را به دو دسته ی دادههای آموزشی و اعتبارسنجی (آزمایشی) تقسیم نمود. از دادههای آموزشی برای تهیه مدل و از دادههای اعتبارسنجی برای آزمایش صحت مدل با ایجاد سوالاتی در مورد صحت پیش بینیها استفاده نمود. پس از تعریف ساختار کاوشی، می بایست به پردازش مدل پرداخته شود و ساختارهای خالی با الگوهایی که مدل را توصیف می نمایند، پُر شوند. این مرحله با عنوان آموزش مدل شناخته می شود.
- بررسی و ارزیابی مدلها (Exploring and Validating Models):
این مرحله شامل بررسی مدلهای ایجاد شده به منظور آزمودن کارایی آنهاست. می توان مدلها را با ابزارهای موجود در Designer از جمله نمودار صعود و یا ماتریس دسته بندی بررسی نمود.
- اجرا و بروزرسانی مدلها (Deploying and Updating Models):
این مرحله شامل اجرای مدل هایی است که بهترین کارائی را در یک محیط عملیاتی داشته اند. پس از استقرار مدلهای کاوشی در یک محیط عملیاتی می توان از این مدلها برای پیش بینی هایی بهره گرفت.
مراحل سه گانه موجود در ساخت یک مدل کاوش
- ایجاد ساختار کاوشی (Mining Structures): تعریف یک ساختار کاوشی شامل، تعیین تعداد ستونهای ورودی، تعداد ستونهای قابل پیش بینی و الگوریتم وابسته به آن میباشد. ساختار کاوشی یک ساختار داده ای است که محدوده ی داده هایی را که از روی آنها مدلهای کاوش ساخته می شود را تعریف می نماید.
- آموزش مدل (Model Training): یک مدل کاوشی، الگوریتمهای کاوش را به داده هایی که ساختار کاوش ارائه می نماید، اعمال می کند. به بیان دیگر استفاده و کاربرد هر ستون و الگوریتمی که برای ساخت مدل استفاده می شود را تعریف می کند، پس شامل داده منبع اصلی نیست، بلکه شامل اطلاعاتی است که توسط الگوریتم کشف می شود. به آموزش مدل، پردازش مدل نیز گفته میشود و زمانی که یک مدل پردازش می شود داده هایی که توسط ساختار کاوش تعریف شده اند، از طریق الگوریتمهای داده کاوی انتخابی منتقل می شوند، الگوریتم؛ الگوها و روندها را جستجو می کند و در ادامه این اطلاعات در مدل ذخیره می شوند. از این رو پس از یادگیری و آموزش مدل، الگوهای بدست آمده در مدل کاوش ذخیره می شوند.
- پیش بینی مدل (Prediction): غالباً مهمترین مرحله و هدف نهایی در پروژههای داده کاوی است. پیش بینی به کشف اطلاعات ناشناخته با استفاده از الگوهای یافته شده از سوابق دادهها اشاره دارد. در پیش بینی به یک مدل کاوشی آموزش دیده و یک مجموعه داده ی جدید نیاز است. و در طول پیش بینی موتور داده کاوی، قواعد بدست آمده در مرحله یادگیری را در مورد مجموعه داده ی جدید بکار می برد و نتایج پیش بینی را به هر Case ورودی تخصیص می دهد.
Resource Governor، اجازه میدهد تا انواع مختلف Session را بر روی Server طبقه بندی کنید که به نوبه خود چگونگی کنترل تخصیص منابع سرور به فعالیت داده شده را به شما اعطا میکند. این قابلیت کمک میکند که ادامه فرآیندهای OLTP تضمین شود و یک عملکرد قابل پیش بینی فراهم میکند تا توسط فرآیندهای غیر قابل پیش بینی، تحت تاثیر منفی قرار نگیرد. با استفاده از Resource Governor، قادر خواهید بود نحوه دستیابی به Session را به منظور محدود کردن منابع خاص برای SQL Server مشخص کنید. به عنوان مثال میتوانید مشخص کنید که بیش از 20 درصد از پردازنده یا منابع حافظه به گزارشهای در حال اجرا اختصاص داده نشود. هنگامیکه این ویژگی فعال باشد، مهم نیست چه تعداد گزارش در حال اجرا است، آنها هرگز نمیتوانند از تخصیص منابع تعیین شده تجاوز کنند. البته این موضوع عملکرد گزارش گیری را کاهش میدهد ولی عملکرد فرآیندهای OLTP حداقل توسط گزارش ها، دیگر تحت تاثیر منفی قرار نمیگیرد.
1- بررسی اجمالی Resource Governor:
Resource Governor، با کنترل تخصیص منابع بر حسب Workload کار میکند. هنگامی که یک درخواست اتصال به موتور بانک اطلاعاتی ارسال میشود درخواست براساس یک تابع رده بندی (Classification function) طبقه بندی میشود. تابع رده بندی یک تابع اسکالر است که از طریق T-SQL تعریف میشود. تابع رده بندی، اطلاعات را درباره یک اتصال (برای مثال login ID، application name، hostname، server role ) ارزیابی میکند، به منظور تشخیص اینکه چگونه آنها را دسته بندی کند. پس از دسته بندی درخواست اتصال، آنها به گروههای حجم کاری (Workload Group) که برای رده بندی تعریف شده اند، شکسته میشوند. هر Workload Group مرتبط با یک مخزن منابع (Resource Pool) است.
یک Resource Pool، منابع فیزیکی SQL Server را نمایش میدهد (در حال حاضر در SQL Server 2008، تنها منابع فیزیکی موجود برای پیکربندی پردازنده و حافظه است) و مقدار حداکثر پردازنده و یا منابع حافظه را که به نوع خاصی از Workload اختصاص داده میشود، تعیین میکند. هنگامی که یک اتصال طبقه بندی شده و در Workload Group صحیح خود قرار میگیرد به این اتصال، پردازنده و منابع حافظه به اندازه نسبت داده شده به آن تخصیص داده میشود و سپس Query به Query Optimizer برای اجرا داده میشود.
2- اجزای Resource Governor:
Resource Governor، از سه قسمت اصلی تشکیل شده است: Classification، Workload Groups و Resource Pools. درک این سه قسمت و چگونگی تعامل آنها به درک و استفاده از Resource Governor کمک میکند.
2-1- Classification:
Classification، فرآیند ارزیابی اتصالات ورودی کاربر و اختصاص آن به یک Workload Group است که توسط منطق موجود در یک تابع تعریف شده توسط کاربر (user-defined function) انجام میشود. تابع نام یک Workload Group را برمی گرداند که Resource Governor از آن برای مسیر دهی Session به Workload Group مناسب استفاده میکند.
هنگامی که Resource Governor پیکربندی میشود فرآیند ورود به سیستم برای یک Session شامل گامهای زیر است:
• Login authentication2-2- Workload Groups:
• LOGON trigger execution
• Classification
Workload Groups، ظروفی برای اتصالات مشابه هستند که با توجه به معیارهای طبقه بندی برای هر اتصال گروه بندی میشوند. Workload Groups همچنین مکانیسمی برای تجمیع نظارت بر روی منابع مصرفی فراهم میکند.
Resource Governor دو Workload Group از پیش تعریف شده دارد: یک گروه داخلی (internal group) و یک گروه پیش فرض (default group).
Internal Workload Group، تنها توسط فرآیندهای داخلی موتور بانک اطلاعاتی استفاده میشود. معیارهای طبقه بندی را برای گروههای داخلی نمیتوانید تغییر دهید و همچنین هیچ یک از درخواستهای کاربران را برای انتقال به گروه داخلی نمیتوانید رده بندی کنید، با این حال بر گروه داخلی میتوانید نظارت کنید.
درخواستهای اتصال به طور خودکار هنگامی که شرایط زیر وجود دارد، به Default Workload Group رده بندی میشوند:
• معیاری برای طبقه بندی درخواست وجود ندارد.Resource Governor، در مجموع 20 عدد Workload Group را پشتیبانی میکند. از آنجائی که دو عدد از آنها برای Workload Groupهای داخلی و پیش فرض ذخیره شده اند در مجموع 18 عدد Workload Group تعریف شده توسط کاربر (user-defined) میتوان تعریف نمود.
• کوششی برای رده بندی درخواستی به گروهی که وجود ندارد.
• خرابی کلی Classification
2-3- Resource pools:
Resource Pool (مخزن منابع)، نشان دهنده تخصیص منابع فیزیکی به SQL Server است. یک Resource Pool از دو بخش تشکیل شده است:
• در بخش نخستین حداقل رزرو منابع را مشخص میکنیم، این بخش از مخزن منابع با مخازن دیگر همپوشانی نمیکند.در 2008 SQL Server مخزن منابع با تعیین حداقل و حداکثر تخصیص CPU و حداقل و حداکثر تخصیص حافظه تنظیم میگردد. با تنظیم حداقل، در دسترس بودن منبع از مخزن تضمین میشود. از آنجائی که در هر رزرو حداقل منابع تداخلی نمیتواند وجود داشته باشد، مجموع مقادیر حداقل در تمام مخازن از 100% کل منابع Server نمیتواند تجاوز کند.
• در بخش دیگر حداکثر ممکن رزرو منابع را برای مخزن مشخص میکنیم، تخصیص منابع با مخازن دیگر مشترک است.
مقدار حداکثر در محدوده بین حداقل و شامل 100% مقدار میتواند تنظیم گردد. تنظیم حداکثر نشان دهنده مقدار حداکثری است که یک Session میتواند مصرف کند، مادامی که منابع در دسترس باشند و توسط مخزن دیگر که با حداقل مقدار غیر صفر پیکربندی شده، استفاده نشود. هنگامی که یک مخزن با حداقل مقدار غیر صفر تعریف شده، مقدار حداکثر موثر از مخزنهای دیگر دوباره تنظیم میشوند، در صورت لزوم حداکثر مقدار موجود از جمع کل حداقل منابع مخازن دیگر کسر میگردد.
برای مثال، دو مخزن تعریف شده توسط کاربر (user-defined) را در نظر بگیرید. مخزن اول Pool1 با مقدار حداقل 20% و مقدار حداکثر 100% تعریف شده، مخزن دیگری Pool2 با مقدار حداقل 50% و مقدار حداکثر 70% تعریف شده است. حداکثر مقدار موثر برایPool1 برابر 50% است (100% منهای مقدار حداقل 50% مخزن Pool2) و حداکثر مقدار موثر برای Pool2، 70% است زیرا حداکثر مقداری است که پیکربندی شده است، گر چه 80% باقی میماند.
بخش مشترکی از مخزن (مقدارش بین مقدار حداقل و مقدار حداکثر موثر است) که برای تعیین مقدار منابع مورد استفاده است، توسط مخزن میتواند مصرف شود اگر منابعی موجود باشد و توسط مخازن دیگر مصرف نشده باشد. هنگامی که منابعی توسط یک مخزن مصرف میشوند، آنها به یک مخزن مشخص نسبت داده میشوند، به بیان دیگر اشتراکی نیستند تا زمانی که فرآیند در آن مخزن به اتمام برسد.
برای توضیح بیشتر یک سناریو که در آن سه مخزن تعریف شده توسط کاربر (user-defined) وجود دارد، را در نظر بگیرید:
PoolA با حداقل مقدار 10% و حداکثر مقدار 100% تعریف میشود.
PoolB با حداقل مقدار 35% و حداکثر مقدار 90% تعریف میشود.
PoolC با حداقل مقدار 30% و حداکثر مقدار 80% تعریف میشود.
مقدار موثر PoolA و مجموع در صد منابع به اشتراک گذاشته PoolA به شرح زیر محاسبه خواهد شد:
( حداکثر مقدار PoolA ) - ( حداقل مقدار PoolB ) - ( حداقل مقدار PoolC ) = ( حداکثر مقدار موثر PoolA )
(حداکثر مقدار موثر PoolA ) – ( حداقل مقدار PoolA ) = ( اشتراک PoolA )
جدول زیر مقدار حداکثر موثر و اشتراکی را برای هر مخزن در این پیکربندی نمایش میدهد:
Internal Pool، منابع مصرف شده توسط فرآیندهای داخلی موتور بانک اطلاعاتی را نشان میدهد. این مخزن تنها شامل گروههای داخلی است و به هیچ وجه قابل تغییر نیست. مخزن داخلی مقدار ثابت حداقل صفر و حداکثر 100% را دارد و مصرف منابع توسط مخزن داخلی، از طریق تنظیمات در هر مخزن دیگر محدود یا کاسته نمیشود.
به عبارت دیگر حداکثر مقدار موثر مخزن داخلی همیشه 100% است. هر workloads در مخزن داخلی برای عملکرد Server حیاتی در نظر گرفته میشود و Resource Governor در صورت لزوم اجازه میدهد تا مخازن داخلی 100% منابع موجود را مصرف کند حتی اگر به معنی نقض نیازمندیهای منابع از سایر مخازن باشد.
Default Pool، اولین مخزن تعریف شده کاربر است. قبل از هرگونه پیکربندی، Default Pool تنها حاوی Default group است. Default Pool نمیتواند ایجاد یا حذف شود اما میتواند تغییر کند. Default Pool علاوه بر Default group میتواند شامل گروههای تعریف شده توسط کاربر (user-defined) نیز باشد.
3- پیکر بندی Resource Governor :
پیکربندی Resource Governor شامل مراحل زیر است:
- فعال کردن Resource Governor3-1- فعال کردن Resource Governor
- ایجاد مخازن منابع (Resource Pools) تعریف شده توسط کاربر (user-defined)
- تعریف Workload Groups و نسبت دادن آن به مخازن
- ایجاد Classification function
- ثبت Classification function به Resource Governor
پیش از اینکه بتوانید یک Resource Pool را ایجاد کنید، نیاز است تا نخست Resource Governor را فعال کنید.
3-2- تعریف Resource Pool
ویژگیهای موجود برای یک Resource Pool عبارتند از:
Name، Minimum CPU %، Maximum CPU%، Min Memory%، Max Memory%
3-3- تعریف Workload Group
پس از اینکه Resource Pool را تعریف کردید، گام بعدی ایجاد یک Workload Group و اختصاص آن به Resource Pool مناسب است. چندین workgroup را میتوان به مخزن (Pool) یکسان نسبت داد اما یک workgroup را به چندین Resource Pool نمیتوان نسبت داد. خواص انتخابی موجود برای Workload Groups به شما اجازه میدهد سطح بهتری از کنترل را روی اجرای دستورات یک Workload Group تنظیم کنید. انتخابهای موجود عبارتند از:
3-3-1- Importance :
اهمیت نسبی (کم، متوسط یا بالا) Workload Group درون Resource Pool را تعیین میکند. اگر چندین Workload Group را در یک Resource Pool تعریف کنید این تنظیمات تعیین میکند که درخواستها در عرض یک Workload Group در اولویت بالاتر یا پائینتری از Workload Groupهای دیگر درون همان Resource Pool اجرا شوند، مقدار متوسط تنظیم پیش فرض است. در حال حاضر فاکتورهای وزنی برای هر تنظیم کم برابر 1، متوسط برابر3 و زیاد برابر 9 است. به این معنی که زمانبند به اجرای Sessionهای درون workgroup هائی با اهمیت بالا، سه برابر بیشتر از workgroupهای با اهمیت متوسط و نه برابر بیشتر از workgroupهای کم اهمیت، مبادرت خواهد کرد.
3-3-2- Maximum Request :
حداکثر تعداد درخواستهای همزمان که اجازه دارند در یک Workload Group اجرا شوند را مشخص میکند. تنظیم پیش فرض، صفر، تعداد نامحدود دستور را اجازه میدهد.
3-3-3- CPU Time :
حداکثر مقدار زمان پردازنده در ثانیه را مشخص میکند که یک درخواست درون Workload Group میتواند استفاده کند. تنظیم پیش فرض، صفر، به معنی نامحدود است.
3-3-4- Memory Grant %:
به صورت در صد، حداکثر مقدار اعطا حافظه برای اجرا (Execution grant memory)، که یک تک دستور از Resource Pool میتواند اخذ کند را مشخص میکند. این درصد نسبی است از مقدار حافظه ای که به Resource Pool نسبت داده میشود. محدوده مجاز مقادیر از 0 تا 100 است. تنظیم پیش فرض 25 است.
Execution grant memory، مقدار حافظه ای است که برای اجرای query استفاده میشود (نه برای Buffer کردن یا cache کردن) که میتواند صرفه نظر از Resource Pool یا Workload Group توسط تعدادی از Sessionها به اشتراک گذاشته شود. توجه شود که تنظیم این مقدار به صفر از اجرای عملیات Hash Join و دستورات مرتب سازی در Workload Groupهای تعریف شده توسط کاربر (user-defined)جلوگیری میکند. همچنین این مقدار توصیه نمیشود بیشتر از 70 باشد زیرا ممکن است Server قادر نباشد، اگر Queryهای همزمان در حال اجرا باشند، حافظه آزاد کافی اختصاص دهد.
3-3-5- Grant Time-out :
حداکثر زمان، به ثانیه، که یک query برای یک منبع منتظر میماند تا در دسترس شود را مشخص میکند. اگر منبع در دسترس نباشد، فرآیند ممکن است با یک خطای time-out مواجه شود. تنظیم پیش فرض، صفر، به معنی این است که سرور time-out را با استفاده از محاسبات داخلی بر مبنای هزینه پرس و جو ( query cost ) با تعیین حداکثر زمان برآورد میکند.
3-3-6- Degree of Parallelism :
حداکثر درجه موازی سازی (DOP) را برای پرس و جوهای موازی تعیین میکند. محدوده مجاز مقادیر از 0 تا 64 است. تنظیم پیش فرض، صفر، به معنی این است که فرآیندها از تنظیمات عمومی استفاده میکنند.
3-4- ایجاد یک Classification function
پس از تعریف Resource Pool و Workload Group، به یک Classification function نیاز است که شامل منطق ارزیابی اتصالات و نسبت دادن آنها به Workload Group مناسب است. Classification function برای هر اتصال Session جدید به SQL Server بکار میرود. هر Session در Workload Group نسبت داده شده به آن باقی میماند تا زمانی که به پایان برسد، مگر اینکه صراحتاً به یک گروه متفاوت دوباره نسبت داده شود. فقط یک Classification function فعال در هر زمان میتواند وجود داشته باشد. در صورت عدم تعریف شدن یا عدم فعال بودن Classification function همه اتصالات به Workload Group Default نسبت داده میشوند. Classification function یک نام workgroup که نوع آن SYSNAME است (که یک نام مستعار برای دیتا تایپ nvarchar 128 است.) برمی گرداند. اگر تابع تعریف شده مقدار 'NULL ،'Default یا نام گروهی که وجود ندارد را برگرداند، Session به Workload Group Default نسبت داده میشود. همچنین اگر به هر دلیلی تابع با موفقیت خاتمه نیابد Session به Workload Group Default نسبت داده میشود.
منطق Classification function معمولاً مبتنی بر ویژگیهای اتصال است و اغلب از طریق مقدار بازگشتی توابع سیستمی از قبیل:
()SUSER_NAME() ،SUSER_SNAME() ،IS_MEMBER() ،IS_SERVERROLEMEMBER() ،HOST_NAME و یا ()APP_NAME، نام Workload Group اتصال مشخص میشود. علاوه بر این توابع میتوانید از ویژگیهای توابع دیگر برای ساخت منطق رده بندی استفاده کنید. تابع ()LOGINPROPERTY شامل دو ویژگی (DefaultDatabase و DefaultLanguage) میباشد که میتواند برای Classification function استفاده شود. بعلاوه تابع ()CONNECTIONPROPERTY پروتکلها و دسترسی به نقل و انتقالات در شبکه، همچنین جزئیات طرح احراز هویت، Local IP address و TCP Port و Client’s IP Address را برای استفاده اتصالات فراهم میکند. برای مثال میتوانید برای یک اتصال، یک Workload Group نسبت دهید، مبتنی بر اینکه subnet یک اتصال ازکجا میآید.
نکته: اگر قصد دارید از هر یک از توابع ()HOST_NAME و یا ()APP_NAME در تابع رده بندی تان استفاده کنید، توجه داشته باشید این امکان وجود دارد مقادیر بازگردانده شده توسط این توابع توسط کاربران تغییر داده شوند، گر چه به طور کلی گرایش به استفاده از تابع ()APP_NAME برای رده بندی اتصالات بیشتر است.
4- بررسی نمونه ای از پیکربندی Resource Governor
برای سادگی، در این قسمت مثالی ارائه میشود که از تابع ()SUSER_NAME استفاده میکند: در گام نخست، دو Resource Pool ایجاد میشود ( ReportPool و OLTPPool )
می توان تابع ()WorkgroupClassifier را در محیط SSMS با اجرای دستور زیر برای Loginهای متفاوت تست نمود:
در ادامه دستور زیر برای پیکربندی تابع رده بندی به Resource Governor استفاده میشود:
5- اصلاح پیکربندی Resource Governor:
میتوانید درمحیط SSMS تنظیمات Resource Pool و Workload Group را تغییر دهید ( برای مثال حداکثر استفاده CPU برای یک Resource Pool و یا درجه اهمیت یک Workload Group). متناوباً میتوان از دستورات T-SQL استفاده نمود.
نکته: پس از اجرای دستورات ALTER RESOURCE POOL یا ALTER WORKLOAD GROUP، برای اعمال کردن تغییرات اجرای دستور ALTER RESOURCE GOVERNOR RECONFIGURE نیاز میباشد.
5-1- حذف Workload Group :
یک Workload Group را اگر هر نوع Session فعال نسبت داده شده به آن وجود داشته باشد، نمیتوان حذف نمود. اگر یک Workload Group شامل Sessionهای فعال باشد، حذف Workload Groupو یا جابجائی آن به یک Resource Pool متفاوت، هنگامی که دستور ALTER RESOURCE GOVERNOR RECONFIGURE برای اعمال نمودن تغییرات فراخوانی میشود، با خطا مواجه خواهد شد.
5-2- حذف Resource Pools:
یک Resource Pool را اگر هر نوع Workload Group نسبت داده شده به آن وجود داشته باشد، نمیتوان حذف نمود. نخست نیاز دارید Workload Group حذف شود و یا به Resource Pool دیگری جابجا گردد.
5-3- اصلاح Classification function:
اگر نیاز دارید تغییراتی در تابع رده بندی ایجاد نمائید، مهم است توجه داشته باشید که تابع رده بندی تا زمانی که مشخص شده (marked) برای Resource Governor است، نمیتوان آنرا حذف و یا تغییر داد. پیش از اینکه بتوان تابع رده بندی را اصلاح و یا حذف نمود نخست نیاز دارید Resource Governor را غیر فعال نمائید. متناوباً میتوان تابع رده بندی را جایگزین کرد با اجرای دستور ALTER RESOURCE GOVERNOR و فرستادن (passing) یک اسم متفاوت برای CLASSIFIER_FUNCTION،همچنین میتوان با اجرای دستور زیر تابع رده بندی جاری را غیر فعال نمود:
تابع رده بندی میتوان تعریف کرد که نام Workload Group را از جداول یک بانک اطلاعاتی جستجو کند به جای اینکه نام Workload Group به صورت hard-coding و مطابق با ضوابط درون تابع باشد. عملکرد، در موقع دسترسی به جدول برای جستجو کردن نام Workload Group، نباید تا حد زیادی تحت تاثیر قرار گیرد.
6- نظارت بر Resource Governor
با استفاده از Performance Monitor، events و (Dynamic Management View (DMV میتوان Workload Group و Resource Pool را نظارت (Monitor) کرد. دو شی Performance برای این کار موجود است: SQL Server:Workload Group Stats و SQL Server:Resource Pool Stats
شکل زیر مربوط به پیکر بندی مثال مورد نظرمان میباشد:
7- نتیجه گیری
Resource Governor چندین مزیت بالقوه ارائه میدهد، در درجه اول قابلیت اولویت بندی منابع Server برای کاربران و برنامههای کاربردی (applications) بحرانی، جلوگیری از “runaway” یا درخواستهای غیر منتظره ای که به شدت و بطور قابل توجهی روی کارائی Server تاثیر منفی میگذارند.
ضمناً Resource Governor چندین مشکل بالقوه نیز عرضه میکند، برای مثال پیکربندی اشتباه Resource Governor تنها به عملکرد کلی Server آسیب نمیرساند بلکه به طور بالقوه روی سرور قفل (Lock) میتواند ایجاد کند و نیاز به استفاده از اتصال اختصاصی Administrator برای متصل شدن به SQL Server به منظور اشکال یابی و رفع مشکل میباشد. بنابراین توصیه شده است که تنها در صورتی که DBA با تجربه ای هستید و درک خوب و آشنائی خوبی با Workload هائی که روی بانک اطلاعاتی اجرا میشوند دارید، Resource Governor را بکار برید. حتی در این صورت، ضروری است که پیکربندی تان را روی یک Server تستی پیش از اینکه روی محیط تولیدی بگسترانید، تست نمائید.
Resource Governor به عنوان یک ویژگی با نام تجاری جدید در SQL Server 2008، با تعدادی محدودیت همراه است که احتمالاً در نسخههای بعدی SQL Server حذف خواهد شد، از محدودیت های بارز :
- محدودیت منابع (Resource)، که به CPU و حافظه محدود میشوند. I/O Disk و منابع شبکه را در SQL Server 2008 نمیتوان محدود کرد.
- استفاده از منابع برای Reporting Service، Analysis Service و Integeration Service را نمیتوان محدود کرد . در این نسخه محدودیتهای منابع تنها روی هسته موتور بانک اطلاعاتی بکار برده میشود.
- محدودیتهای Resource Governor روی یک SQL Instance تعریف و بکار برده میشود.
یک مشکلی که هست، وقتی متن (این) صفحه رو با این روش پردازش میکنم، کاراکترهای نامفهومی نمایش داده میشه.. Encoding رو چطور تنظیم کنم، یا مشکل از جای دیگه ای هست؟
برای مثال InnerText این XPath:
/html[1]/body[1]/table[1]/tr[1]/td[1]/table[1]/tr[1]/td[2]/table[1]/tr[1]/td[1]/font[1]/td[2]/font[1]/td[1]/map[1]/tr[3]/td[1]/table[1]/tr[1]/td[1]/table[1]/tr[3]/td[1]/table[1]/tr[1]/td[1]/table[1]/tr[1]/td[1]/table[1]/tr[1]/td[2]/a[1]/td[1]/a[1]/table[3]/tr[2]/td[2]/table[1]/tr[1]/td[1]/div[1]/span[1]/span[1]/html[1]/head[1]/title[1]/text()[1]
2. اگر بخوام برای یک منظور، تاریخ (فقط تاریخ، بدون زمان) رو نگهداری کنم ، توصیه شما برای نوع داده ای پایگاه داده، و نیز روش درست ذخیره و بازیابی چی هست؟
متشکرم
چگونه کدها را مستند سازی کنیم؟
آشنایی با مدل برنامه نویسی TAP
دات نت فریم ورک، از زمان ارائه نگارش یک آن، از اعمال غیرهمزمان و API خاص آن پشتیبانی میکردهاست. همچنین این مورد یکی از ویژگیهای Win32 نیز میباشد. نوشتن کدهای همزمان متداول بسیار ساده است. در این نوع کدها هر عملیات خاص، پس از پایان عملیات قبلی انجام میشود.
public string TestNoneAsync() { var webClient = new WebClient(); return webClient.DownloadString("http://www.google.com"); }
این مورد همچنین در برنامههای سمت سرور نیز حائز اهمیت است. با قفل شدن تعداد زیادی ترد در حال اجرا، عملا قدرت پاسخدهی سرور نیز کاهش مییابد. بنابراین در این نوع موارد، برنامههای چند ریسمانی هرچند در سمت کلاینت ممکن است مفید واقع شوند و برای مثال ترد UI را آزاد کنند، اما اثر آنچنانی بر روی برنامههای سمت سرور ندارند. زیرا در آنها میتوان هزاران ترد را ایجاد کرد که همگی دارای کدهای اصطلاحا blocking باشند. برای حل این مساله استفاده از API غیرهمزمان توصیه میشود.
برای نمونه کلاس WebClient توکار دات نت، دارای متدی به نام DownloadStringAsync نیز میباشد. این متد به محض فراخوانی، ترد جاری را آزاد میکند. به این معنا که فراخوانی آن سبب توقف ترد جاری برای دریافت نتیجهی دریافت اطلاعات از وب نمیشود. به این نوع API، یک Asynchronous API گفته میشود؛ زیرا با سایر کدهای نوشته شده، هماهنگ و همزمان اجرا نمیشود.
هر چند این کد جدید مشکل عدم پاسخ دهی برنامه را برطرف میکند، اما مشکل دیگری را به همراه دارد؛ چگونه باید حاصل عملیات آنرا پس از پایان کار دریافت کرد؟ چگونه باید خطاها و مشکلات احتمالی را مدیریت کرد؟
برای مدیریت این مساله، رخدادی به نام DownloadStringCompleted تعریف شدهاست. روال رویدادگردان آن پس از پایان کار دریافت اطلاعات از وب، فراخوانی میگردد.
public void TestAsync() { var webClient = new WebClient(); webClient.DownloadStringAsync(new Uri("http://www.google.com")); webClient.DownloadStringCompleted += webClientDownloadStringCompleted; } void webClientDownloadStringCompleted(object sender, DownloadStringCompletedEventArgs e) { // use e.Result }
مشکل! ما سادگی یک عملیات همزمان را از دست دادیم. متد TestNoneAsync از لحاظ پیاده سازی و همچنین خواندن و نگهداری آن در طول زمان، بسیار سادهتر است از نمونهی TestAsync نوشته شده. در کدهای غیرهمزمان فوق، یک متد ساده، به دو متد مجزا خرد شدهاست و نتیجهی نهایی، درون یک روال رخدادگردان بدست میآید.
به این مدل، EAP یا Event based asynchronous pattern نیز گفته میشود. EAP در دات نت 2 معرفی شد. روالهای رخدادگردان در این حالت، در ترد اصلی برنامه اجرا میشوند. اما اگر به حالت اصلی اعمال غیرهمزمان موجود از دات نت یک کوچ کنیم، اینطور نیست. در WinForms و WPF برای به روز رسانی رابط کاربری نیاز است اطلاعات دریافت شده در همان تردی که رابط کاربری ایجاد شده است، تحویل گرفته شده و استفاده شوند. در غیراینصورت استثنایی صادر شده و برنامه خاتمه مییابد.
آشنایی با Synchronization Context
ابتدا یک برنامهی WinForms ساده را آغاز کرده و یک دکمهی جدید را به نام btnGetInfo و یک تکست باکس را به نام txtResults، به آن اضافه کنید. سپس کدهای فرم اصلی آنرا به نحو ذیل تغییر دهید:
using System; using System.Linq; using System.Net; using System.Windows.Forms; namespace Async02 { public partial class Form1 : Form { public Form1() { InitializeComponent(); } private void btnGetInfo_Click(object sender, EventArgs e) { var req = (HttpWebRequest)WebRequest.Create("http://www.google.com"); req.Method = "HEAD"; req.BeginGetResponse( asyncResult => { var resp = (HttpWebResponse)req.EndGetResponse(asyncResult); var headersText = formatHeaders(resp.Headers); txtResults.Text = headersText; }, null); } private string formatHeaders(WebHeaderCollection headers) { var headerString = headers.Keys.Cast<string>() .Select(header => string.Format("{0}:{1}", header, headers[header])); return string.Join(Environment.NewLine, headerString.ToArray()); } } }
همچنین در این مثال از متد غیرهمزمان BeginGetResponse نیز استفاده شدهاست. در این نوع API خاص، کار با BeginGetResponse آغاز شده و سپس در callback نهایی توسط EndGetResponse، نتیجهی عملیات به دست میآید.
اگر برنامه را اجرا کنید، با استثنای زیر مواجه خواهید شد:
An exception of type 'System.InvalidOperationException' occurred in System.Windows.Forms.dll but was not handled in user code Additional information: Cross-thread operation not valid: Control 'txtResults' accessed from a thread other than the thread it was created on.
private void btnGetInfo_Click(object sender, EventArgs e) { var sync = SynchronizationContext.Current; var req = (HttpWebRequest)WebRequest.Create("http://www.google.com"); req.Method = "HEAD"; req.BeginGetResponse( asyncResult => { var resp = (HttpWebResponse)req.EndGetResponse(asyncResult); var headersText = formatHeaders(resp.Headers); sync.Post(delegate { txtResults.Text = headersText; }, null); }, null); }
برای درک بهتر آن، سه break point را پیش از متد BeginGetResponse، داخل Async calback و داخل delegate متد Post قرار دهید. پس از اجرای برنامه، از منوی دیباگ در VS.NET گزینهی Windows و سپس Threads را انتخاب کنید.
در اینجا همانطور که مشخص است، کد داخل delegate تعریف شده، در ترد اصلی برنامه اجرا میشود و نه یکی از Worker threadهای ثانویه.
هر چند استفاده از متدهای تو در تو و lambda syntax، نیاز به تعریف چندین متد جداگانه را برطرف کردهاست، اما باز هم کد سادهای به نظر نمیرسد. در سی شارپ 5، برای مدیریت بهتر تمام مشکلات یاد شده، پشتیبانی توکاری از اعمال غیرهمزمان، به هستهی زبان اضافه شدهاست.
Syntax ابتدایی یک متد Async
در ابتدا کلاس و متد Async زیر را در نظر بگیرید:
using System; using System.Threading.Tasks; namespace Async01 { public class AsyncExample { public async Task DoWorkAsync(int parameter) { await Task.Delay(parameter); Console.WriteLine(parameter); } } }
- در مدل برنامه نویسی TAP، متدهای غیرهمزمان باید یک Task را بازگشت دهند؛ یا نمونهی جنریک آنرا. البته کامپایلر، async void را نیز پشتیبانی میکند ولی در قسمتهای بعدی بررسی خواهیم کرد که چرا استفاده از آن مشکلزا است و باید از آن پرهیز شود.
- همچنین مطابق TAP، اینگونه متدها باید به پسوند Async ختم شوند تا استفاده کننده در حین کار با Intellisense، بتواند آنها را از متدهای معمولی سریعتر تشخیص دهد.
- از واژهی کلیدی async نیز استفاده میگردد تا کامپایلر از وجود اعمال غیر همزمان مطلع گردد.
- await به کامپایلر میگوید، عبارت پس از من، یک وظیفهی غیرهمزمان است و ادامهی کدهای نوشته شده، تنها زمانی باید اجرا شوند که عملیات غیرهمزمان معرفی شده، تکمیل گردد.
در متد DoWorkAsync، ابتدا به اندازهای مشخص توقف حاصل شده و سپس سطر بعدی یعنی Console.WriteLine اجرا میشود.
یک اشتباه عمومی! استفاده از واژههای کلیدی async و await متد شما را async نمیکنند.
برخلاف تصور ابتدایی از بکارگیری واژههای کلیدی async و await، این کلمات نحوهی اجرای متد شما را async نمیکنند. این کلمات صرفا برای تشکیل متدهایی که هم اکنون غیرهمزمان هستند، مفید میباشند. برای توضیح بیشتر آن به مثال ذیل دقت کنید:
public async Task<double> GetNumberAsync() { var generator = new Random(); await Task.Delay(generator.Next(1000)); return generator.NextDouble(); }
در ادامه برای استفاده از آن خواهیم داشت:
public async Task<double> GetSumAsync() { var leftOperand = await GetNumberAsync(); var rightOperand = await GetNumberAsync(); return leftOperand + rightOperand; }
در کدهای همزمان متداول، سطر اول ابتدا انجام میشود و بعد سطر دوم و الی آخر. با استفاده از واژهی کلیدی await یک چنین عملکردی را با اعمال غیرهمزمان خواهیم داشت. پیش از این برای مدیریت اینگونه اعمال از یک سری callback و یا رخداد استفاده میشد. برای مثال ابتدا عملیات همزمانی شروع شده و سپس نتیجهی آن در یک روال رخداد گردان جایی در کدهای برنامه دریافت میشد (مانند مثال ابتدای بحث). اکنون تصور کنید که قصد داشتید جمع نهایی حاصل دو عملیات غیرهمزمان را از دو روال رخدادگردان جدا از هم، جمع آوری کرده و بازگشت دهید. هرچند اینکار غیرممکن نیست، اما حاصل کار به طور قطع آنچنان زیبا نبوده و قابلیت نگهداری پایینی دارد. واژهی کلیدی await، انجام اینگونه امور غیرهمزمان را طبیعی و همزمان جلوه میدهد. به این ترتیب بهتر میتوان بر روی منطق و الگوریتمهای مورد استفاده تمرکز داشت، تا اینکه مدام درگیر مکانیک اعمال غیرهمزمان بود.
امکان استفاده از واژهی کلیدی await در هر جایی از کدها وجود دارد. برای نمونه در مثال زیر، برای ترکیب دو عملیات غیرهمزمان، از await در حین تشکیل عملیات ضرب نهایی، دقیقا در جایی که مقدار متد باید بازگشت داده شود، استفاده شدهاست:
public async Task<double> GetProductOfSumAsync() { var leftOperand = GetSumAsync(); var rightOperand = GetSumAsync(); return await leftOperand * await rightOperand; }
Operator '*' cannot be applied to operands of type 'System.Threading.Tasks.Task<double>' and 'System.Threading.Tasks.Task<double>'
اگر متد DownloadString همزمان ابتدای بحث را نیز بخواهیم تبدیل به نمونهی async سیشارپ 5 کنیم، میتوان از متد الحاقی جدید آن به نام DownloadStringTaskAsync کمک گرفت:
public async Task<string> DownloadAsync() { var webClient = new WebClient(); return await webClient.DownloadStringTaskAsync("http://www.google.com"); }
سؤال: آیا استفاده از await نیز ترد جاری را قفل میکند؟
اگر به کدها دقت کنید، استفاده از await به معنای صبر کردن تا پایان عملیات async است. پس اینطور به نظر میرسد که در اینجا نیز ترد اصلی، همانند قبل قفل شدهاست.
public void TestDownloadAsync() { Debug.WriteLine("Before DownloadAsync"); DownloadAsync(); Debug.WriteLine("After DownloadAsync"); }
Before DownloadAsync After DownloadAsync
برنامههای Async و نگارشهای مختلف دات نت
شاید در ابتدا به نظر برسد که قابلیتهای جدید async و await صرفا متعلق هستند به دات نت 4.5 به بعد؛ اما خیر. اگر کامپایلری را داشته باشید که از این واژههای کلیدی را پشتیبانی کند، امکان استفاده از آنها را با دات نت 4 نیز خواهید داشت. برای این منظور تنها کافی است از VS 2012 به بعد استفاده نمائید. سپس در کنسول پاورشل نیوگت دستور ذیل را اجرا نمائید (فقط برای برنامههای دات نت 4 البته):
PM> Install-Package Microsoft.Bcl.Async
در مورد افزونه YSlow افزونه Firebug فایرفاکس پیشتر صحبت شد. این افزونه پس از آنالیز یک سایت، پیشنهاداتی را نیز جهت بهبود سرعت، ارائه میدهد.
همانطور که در شکل بالا مشخص است، عناصری مانند css و js ، قسمت expires اشان (تاریخ منقضی شدن کش آنها در سمت کلاینت) خالی است و پیشنهاد داده که به هر کدام از این عناصر، هدر مخصوص مشخص سازی مدت زمان کش شدن در سمت کلاینت اضافه شود.
ASP.Net در مورد کش کردن اطلاعات صفحات پویا به اندازهی کافی امکانات در اختیار برنامه نویس قرار میدهد اما در مورد اضافه کردن این هدر جهت یک فایل css غیر پویا شاید نتوان مطلب خاصی را یافت.
در IIS7 امکانات ویژهای برای این منظور در نظر گرفته شده که نحوه استفاده از آن در ASP.Net به صورت زیر است:
فایل وب کانفیگ سایت را باز کرده و به قسمت system.webServer چند سطر زیر را اضافه کنید:
<staticContent>
<clientCache httpExpires="Sun, 29 Mar 2020 00:00:00 GMT" cacheControlMode="UseExpires" />
</staticContent>
این مورد فقط مختص به IIS7 است و بر روی نگارشهای پایینتر کار نمیکند.
با این کار، تاریخ منقضی شدن هر آنچه که توسط موتور ASP.net سرو نمیشود به سال 2020 تنظیم خواهد شد. (کلیه محتوای غیرپویای سایت، اعم از تصاویر، فایلهای css ، js و غیره)
پس از این تنظیم مجددا YSlow را اجرا کرده و Performance Grade ایی را که نمایش میدهد بررسی نمائید.
بدیهی است اگر یکی از فایلهای css یا js شما تغییر کند، کلاینت، اطلاعات جدیدی را تا سال 2020 دریافت نمیکند. برای حل این مشکل یک کوئری استرینگ ساده به انتهای لینک مربوط به css یا js خود اضافه کنید تا URL جدید با URL قبلی آن یکسان نباشد (این کوئری استرینگ تاثیری روی محتوای ایستای ما ندارد). به این صورت این آدرس جدید، مجددا دریافت شده و تا سال 2020 کش خواهد شد.
نکته:
اعمال تنظیم فوق، در IIS7 ویندوز سرور 2008 مجاز است؛ اما در IIS7 ویندوز ویستا قفل شده است و قابل override نیست. برای تغییر آن، فایل زیر را پیدا کنید:
open %systemroot%\System32\inetsrv\config\applicationHost.config
<section name="staticContent" overrideModeDefault="Deny" />
<section name="staticContent" overrideModeDefault="Allow" />
مآخذ:
YSlow: Add expires header to images in IIS 7
IIS7: How to set cache control for static content?
سازماندهی بهتر کامپوننتهای ngx-bootstrap
پس از نصب بستهی npm کتابخانهی ngx-bootstrap و تنظیم فایل angular-cli.json. که در مطلب «Angular CLI - قسمت ششم - استفاده از کتابخانههای ثالث» بررسی شدند، برای کار با کامپوننتهای این کتابخانه باید متدهای BsDropdownModule.forRoot، TooltipModule.forRoot، ModalModule.forRoot و ... را به قسمت imports فایل app.module.ts اضافه کرد. با انجام اینکار پس از مدتی به یک فایل بسیار شلوغ app.module.ts خواهیم رسید. برای مدیریت بهتر آن میتوان شبیه به مطلب «سازماندهی برنامههای Angular توسط ماژولها» در پوشهی Shared برنامه، ماژول ذیل را تدارک دید. برای اینکار ابتدا فایل جدید src\app\shared\shared.bootstrap.module.ts را ایجاد نمائید. سپس کامپوننتهای این کتابخانه را به صورت ذیل در این تک ماژول اختصاصی قرار دهید:
import { NgModule } from "@angular/core"; import { CommonModule } from "@angular/common"; import { BsDropdownModule } from "ngx-bootstrap/dropdown"; import { TooltipModule } from "ngx-bootstrap/tooltip"; import { ModalModule } from "ngx-bootstrap/modal"; @NgModule({ imports: [ CommonModule, BsDropdownModule.forRoot(), TooltipModule.forRoot(), ModalModule.forRoot() ], exports: [ BsDropdownModule, TooltipModule, ModalModule ] }) export class SharedBootstrapModule { }
اکنون برای استفادهی از SharedBootstrapModule اختصاصی فوق، میتوان دو روش را بکار برد:
الف) import مستقیم آن در فایل app.module.ts
import { SharedBootstrapModule } from './shared/shared.bootstrap.module'; @NgModule({ imports: [BrowserModule, SharedBootstrapModule], // ... }) export class AppModule {}
و یا اگر فایل src\app\shared\shared.module.ts را مطابق مطلب «سازماندهی برنامههای Angular توسط ماژولها» ایجاد کردهاید، این ماژول به صورت ذیل، در دو قسمت imports و exports آن اضافه خواهد شد:
import { SharedBootstrapModule } from "./shared.bootstrap.module"; @NgModule({ imports: [ CommonModule, SharedBootstrapModule ], exports: [ CommonModule, SharedBootstrapModule ] })
نمایش یک modal dialog توسط کامپوننت Modal
پس از تعریف ModalModule.forRoot، اکنون میتوان به کامپوننت Modal این ماژول دسترسی یافت. برای این منظور کامپوننتی که قرار است یک Modal را نمایش دهد، چنین ساختاری را پیدا میکند:
import { Component, OnInit, TemplateRef } from "@angular/core"; import { BsModalRef, BsModalService } from "ngx-bootstrap"; @Component({ selector: "app-modal-dialog-test", templateUrl: "./modal-dialog-test.component.html", styleUrls: ["./modal-dialog-test.component.css"] }) export class ModalDialogTestComponent implements OnInit { modalRef: BsModalRef; constructor(private modalService: BsModalService) { } openModal(template: TemplateRef<any>) { this.modalRef = this.modalService.show(template, { animated: true, keyboard: true, backdrop: true, ignoreBackdropClick: false }); } closeModal() { this.modalRef.hide(); } }
سپس با فراخوانی متد this.modalService.show میتوان این قالب را نمایش داد. خروجی این متد ارجاعی را به این modal بازگشت میدهد. از این ارجاع میتوان در جهت بستن آن استفاده کرد (مانند متد closeModal).
بنابراین در ادامه، قالب کامپوننت مثال این قسمت، یک چنین شکلی را پیدا میکند:
<h1>Displaying modal bootstrap dialogs</h1> <button type="button" class="btn btn-info" (click)="openModal(template1)">Create template modal</button> <ng-template #template1> <div class="modal-header"> <h4 class="modal-title pull-left">Modal</h4> <button type="button" class="close pull-right" aria-label="Close" (click)="closeModal()"> <span aria-hidden="true">×</span> </button> </div> <div class="modal-body"> This is a modal. </div> </ng-template>
طراحی یک کامپوننت عمومی مودال جهت دریافت تائید انجام عملیات
در ادامه میخواهیم توسط یک modal dialog، کار دریافت تائید و یا لغو انجام یک عملیات را انجام دهیم. چون این کامپوننت عمومی قرار است در بیش از یک ماژول استفاده شود، بنابراین نیاز است آنرا در Shared Module ثبت کرد. به همین جهت این کامپوننت را به نحو ذیل در پوشهی Shared ایجاد میکنیم:
ng g c Shared/ConfirmModal --skip-import
import { ConfirmModalComponent } from "./confirm-modal/confirm-modal.component"; @NgModule({ imports: [ ], entryComponents: [ ConfirmModalComponent ], declarations: [ ConfirmModalComponent ] }) export class SharedModule {}
این کامپوننت دریافت تائید کاربر به صورت ذیل تعریف میشود:
import { Component } from "@angular/core"; @Component({ selector: "app-confirm-modal", templateUrl: "./confirm-modal.component.html", styleUrls: ["./confirm-modal.component.css"] }) export class ConfirmModalComponent { args: { title: string; message: string; }; close: (val?: any) => void; }
قالب این کامپوننت نیز بدون استفاده از ng-template تعریف میشود:
<div class="modal-header"> <h4 class="modal-title pull-left">{{ args?.title }}</h4> <button type="button" class="close pull-right" aria-label="Close" (click)="close()"> <span aria-hidden="true">×</span> </button> </div> <div class="modal-body"> <p>{{ args?.message }}</p> </div> <div class="modal-footer"> <button class="btn btn-danger" (click)="close(true)">Yes</button> <button class="btn btn-primary" (click)="close()">Cancel</button> </div>
تا اینجا یک کامپوننت نمایش دریافت تائید انجام عملیات را تهیه کردیم. در ادامه نیاز است یک سرویس را جهت بارگذاری پویای اینگونه کامپوننتهای مودال طراحی کنیم. این سرویس عمومی در پوشهی Core و CoreModule ثبت خواهد شد:
>ng g s Core/Modal
import { Injectable } from "@angular/core"; import { BsModalService } from "ngx-bootstrap"; @Injectable() export class ModalService { constructor(private bsModalService: BsModalService) { } show(component: any, args?: any, options?: any): Promise<any> { return new Promise(resolve => { options = options || {}; const modal = this.bsModalService.show(component, options); let result: any; const sub = this.bsModalService.onHidden.subscribe(() => { sub.unsubscribe(); resolve(result); }); modal.content.args = args; modal.content.close = (val?: any) => { result = val; modal.hide(); }; }); } }
یک مودال در سه حالت ممکن است بسته شود:
الف) کلیک بر روی دکمهی close و یا cancel
ب) کلیک بر روی علامت ضربدر درج شدهی در یک سمت عنوان آن
ج) کلیک بر روی قسمتی از صفحه، خارج از مودال
در حالات ب و ج، رخداد this.bsModalService.onHidden فراخوانی میشود. در حالت الف، همان متد close درج شدهی در کامپوننت فراخوانی میشود.
برای اینکه بتوان نتیجهی عملیات را از طرف یک سرویس به کامپوننت فراخوان آن گزارش دهیم، یکی از روشها، استفاده از Promiseها است که مشاهده میکنید. با فراخوانی resolve(result)، کار ارسال نتیجهی فراخوانی متدهای close(true) و ()close صورت میگیرد (یا true و یا undefined).
خاصیت modal.content امکان دسترسی به خواص عمومی کامپوننت در حال استفاده را میسر میکند (content به کامپوننت بارگذاری شده اشاره میکند). اینجا است که میتوان برای مثال به خاصیت args یک کامپوننت، مقادیری را نسبت داد و یا به متد close آن دسترسی یافت.
پس از افزودن این سرویس، محل تعریف آن در قسمت providers مربوط به CoreModule است تا در تمام برنامه قابل دسترسی شود:
import { ModalService } from "./modal.service"; @NgModule({ providers: [ ModalService ] }) export class CoreModule {}
<button type="button" class="btn btn-danger" (click)="deleteRecord()">Delete record</button> <div *ngIf="confirmResult" class="alert alert-info">{{confirmResult}}</div>
import { ModalService } from "./../../core/modal.service"; import { ConfirmModalComponent } from "./../../shared/confirm-modal/confirm-modal.component"; export class ModalDialogTestComponent implements OnInit { confirmResult: string; constructor(private modalService: ModalService) { } deleteRecord() { this.confirmResult = ""; this.modalService.show( ConfirmModalComponent, { title: "Confirm", message: "Do you want to delete this record?" }, { animated: true, keyboard: true, backdrop: true, ignoreBackdropClick: false }).then(confirmed => { if (confirmed) { this.confirmResult = "Deleted!"; } else { this.confirmResult = "Canceled!"; } }); } }
توسط this.modalService.show میتوان انواع و اقسام کامپوننتهای مودال را به صورت پویا بارگذاری کرد و نمایش داد.
کدهای کامل این قسمت را از اینجا میتوانید دریافت کنید.