بازخوردهای دوره
دریافت قالب WpfFramework.vsix و نحوه نصب و راه اندازی آن
با سلام 
با تشکر  بابت شروع این دوره ، می‌خواستم بدونم این فریمورک قراره ماهیت آموزشی داشته باشه یا اینکه توسعه داده میشه؟ آیا می‌تونیم توی توسعه این فریم ورک همکاری داشته باشیم؟
یک باگ کوچیک توی قسمت GetTableName  برای sql server وجود داره، با توجه به نام جدول ترتیب جایگزینی صحیح نیست.
//table="[dbo].[Users]"
    return table
                     .Replace("dbo.", string.Empty)
                     .Replace("`", string.Empty)
                     .Replace("[", string.Empty)
                     .Replace("]", string.Empty)
                     .Trim()


     return table
                     .Replace("`", string.Empty)
                     .Replace("[", string.Empty)
                     .Replace("]", string.Empty)
                     .Replace("dbo.", string.Empty)
                     .Trim();
اشتراک‌ها
EF Core 5.0 Preview 8 منتشر شد

Today, the Entity Framework Core team announces the eighth and final preview release of EF Core 5.0. The next release will be a release candidate (RC). This release includes table-per-type (TPT) mapping, table-valued functions, SQLite table rebuilds for migrations and much more. 

EF Core 5.0 Preview 8 منتشر شد
اشتراک‌ها
طراحی جدول Calendar یا DateDimension

What is a Calendar Table and Why is it Useful?

A calendar table is a permanent table containing a list of dates and various components of those dates. These may be the result of DATEPART operations, time of year, holiday analysis, or any other creative operations we can think of. 

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


طراحی جدول Calendar یا DateDimension
نظرات مطالب
استفاده از Flashback Table در Oracle
برای خالی کردن این فضا از سه حالت دستوری زیر می‌شه استفاده کرد:
Table
 برای آزاد کردن فضای مربوط اشیاء حذف شده برای کاربر جاری: 
PURGE TABLE Table_Name;
  برای آزاد کردن فضای مربوط  کل اشیاء حذف شده برای کاربر جاری: 
 PURGE RECYCLEBIN;
DBA_RecycleBin
برای آزاد کردن فضای مربوط به کل اشیاء حذف شده :
PURGE DBA_RECYCLEBIN;
از این حالت  فقط زمانی که بادسترسی SYSDBA  وارد سیستم شده باشیم می‌توانیم استفده نماییم.

TableSpace
  برای آزاد کردن فضای مربوط به کل اشیاء حذف شده یک TableSpace:

purge Tablespace Tablespace_name;
  
یه میان بر هم برای اینکه بعد از حذف یک شیء به داخل RECYCLEBIN نره استفاده ازاین دستور:
DROP TABLE Table_Name PURGE;
 
مسیرراه‌ها
ASP.NET MVC
              مطالب
              مدیریت پیشرفته‌ی حالت در React با Redux و Mobx - قسمت اول - Redux چیست؟
              Redux و Mobx، کتابخانه‌های کمکی هستند برای مدیریت حالت برنامه‌های پیچیده‌ی React. هرچند React به صورت توکار به همراه امکانات مدیریت حالت است، اما این کتابخانه‌ها مزایای ویژه‌ای را به آن اضافه می‌کنند. در این سری ابتدا کتابخانه‌ی Redux را به صورت خالص و مجزای از React بررسی می‌کنیم. از این کتابخانه در برنامه‌های Angular و Ember هم می‌توان استفاده کرد و به صورت اختصاصی برای React طراحی نشده‌است. سپس آن‌را به برنامه‌های React متصل می‌کنیم. در آخر کتابخانه‌ی محبوب دیگری را به نام Mobx بررسی می‌کنیم که برای مدیریت حالت، اصول برنامه نویسی شیءگرا و همچنین Reactive را با هم ترکیب می‌کند و این روزها در برنامه‌های React، بیشتر از Redux مورد استفاده قرار می‌گیرد.


              چرا به ابزارهای مدیریت حالت نیاز داریم؟

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


              داشتن تنها یک محل برای ذخیره سازی state در برنامه

              همانطور که در قسمت 8 ترکیب کامپوننت‌ها در سری React 16x بررسی کردیم، هر کامپوننت در React، دارای state خاص خودش است و این state از سایر کامپوننت‌ها کاملا مستقل و ایزوله‌است. این مورد با بزرگ‌تر شدن برنامه و برقراری ارتباط بین کامپوننت‌ها، مشکل ایجاد می‌کند. برای مثال اگر بخواهیم دکمه‌ای را در صفحه قرار داده و توسط این دکمه درخواست صفر شدن مقدار هر کدام از شمارشگرها را صادر کنیم، با صفر کردن value هر کدام از این کامپوننت‌ها، اتفاقی رخ نمی‌دهد. چون state محلی این کامپوننت‌ها، با سایر اجزای صفحه به اشتراک گذاشته نمی‌شود و باید آن‌را تبدیل به یک controlled component کرد، بطوریکه دارای local state خاص خودش نیست و تمام داده‌های دریافتی را از طریق this.props دریافت می‌کند و هر زمانیکه قرار است داده‌ای تغییر کند، رخ‌دادی را به والد خود صادر می‌کند. بنابراین این کامپوننت به طور کامل توسط والد آن کنترل می‌شود. تازه این روش در مورد کامپوننت‌هایی صدق می‌کند که رابطه‌ی والد و فرزندی بین آن‌ها وجود دارد. اگر چنین رابطه‌ای وجود نداشت، باید state را به یک سطح بالاتر انتقال داد. برای مثال باید state کامپوننت Counters را به والد آن که کامپوننت App است، منتقل کرد. پس از آن چون کامپوننت‌های ما، از کامپوننت App مشتق می‌شوند، اکنون می‌توان این state را به تمام فرزندان App توسط props منتقل کرد و به اشتراک گذاشت. این مورد هم مانند مثال انتقال اطلاعات کاربر لاگین شده‌ی به سیستم، به تمام زیر قسمت‌های برنامه، نیاز به ارسال اطلاعات از طریق props یک کامپوننت، به کامپوننت بعدی را دارد و به همین ترتیب برای مابقی که به props drilling مشهور است و روش پسندیده‌ای نیست.


              Redux چیست؟ ذخیره سازی کل درخت state یک برنامه، در یک محل. به این ترتیب به یک شیء جاوا اسکریپتی بزرگ خواهیم رسید که در برگیرنده‌ی تمام state برنامه‌است. یکی از مزایای آن امکان serialize و deserialize کل این شیء، به سادگی است. برای مثال توسط متد JSON.stringify می‌توان آن‌را در جائی ذخیره کرد و سپس آن‌را به صورت یک شیء جاو اسکریپتی در زمانی دیگر بازیابی کرد. یکی از مزایای آن، امکان بازیابی دقیق شرایط کاربری است که دچار مشکل شده‌است و سپس دیباگ و رفع مشکل او، در زمانی دیگر.


              تاریخچه‌ای از سیستم‌های مدیریت حالت

              همه چیز با AngularJS 1x شروع شد که از data binding دو طرفه پشتیبانی می‌کرد. هرچند این روش برای همگام نگه داشتن View و مدل برنامه، مفید است، اما در Viewهای پیچیده، برنامه را کند می‌کند. در همین زمان فیس‌بوک، روش مدیریت حالتی را به نام Flux ارائه داد که از data binding یک طرفه پشتیبانی می‌کرد. به این معنا که در این روش، همواره اطلاعات از View به مدل، جریان پیدا می‌کند. کار کردن با آن ساده‌است؛ چون نیازی نیست حدس زده شود که اکنون جریان اطلاعات از کدام سمت است. اما مشکل آن عدم هماهنگی model و view، در بعضی از حالات است. Flux از این جهت به وجود آمد که مدیریت حالت در برنامه‌های React آن زمان، پیچیده بود و مقیاس پذیری کمی داشت (پیش از ارائه‌ی Context و Hooks). در کل Flux صرفا یکسری الگوی مدیریت حالت را بیان می‌کند و یک کتابخانه‌ی مجزا نیست. بر مبنای این الگوها و قراردادها، می‌توان کتابخانه‌های مختلفی را ایجاد کرد. از این رو در سال 2015، کتابخانه‌های زیادی مانند Reflux, Flummox, MartyJS, Alt, Redux و غیره برای پیاده سازی آن پدید آمدند. در این بین، کتابخانه‌ی Redux ماندگار شد و پیروز این نبرد بود!


              توابع خالص و ناخالص (Pure & Impure Functions)

              پیش از شروع بحث، نیاز است با یک‌سری از واژه‌ها مانند توابع خالص و ناخالص آشنا شد. این نکات از این جهت مهم هستند که Redux فقط با توابع خالص کار می‌کند.
              توابع خالص: تعدادی آرگومان را دریافت کرده و بر اساس آن‌ها، مقداری را باز می‌گردانند.
              // Pure
              const add = (a, b) => {
                return a + b;
              }
              در اینجا یک تابع خالص را مشاهده می‌کنید که a و b را دریافت کرده و بر این اساس، یک خروجی کاملا مشخص را بازگشت می‌دهد.

              توابع ناخالص: این نوع توابع سبب تغییراتی در متغیرهایی خارج از میدان دید خود می‌شوند و یا به همراه یک سری اثرات جانبی (side effects) مانند تعامل با دنیای خارج (وجود یک console.log در آن تابع و یا دریافت اطلاعاتی از یک API خارجی) هستند.
              // Impure
              const b;
              
              const add = (a) => {
                return a + b;
              }
              تابع تعریف شده‌ی در اینجا ناخالص است؛ چون با اطلاعاتی خارج از میدان دید خود مانند متغیر b، تعامل دارد. این تعامل با دنیای خارج، حتی در حد نوشتن یک console.log:
              // Impure
              const add = (a, b) => {
                console.log('lolololol');
                return a + b;
              }
              یک تابع خالص را تبدیل به یک تابع ناخالص می‌کند و یا نمونه‌ی دیگر این تعاملات، فراخوانی سرویس‌های backend در برنامه هستند که یک تابع را ناخالص می‌کنند:
              // Impure
              const add = (a, b) => {
                 Api.post('/add', { a, b }, (response) => {
                  // Do something.
                 });
              };


              روش‌هایی برای جلوگیری از تغییرات در اشیاء در جاوا اسکریپت

              ایجاد تغییرات در آرایه‌ها و اشیاء (Mutating arrays and objects) نیز ناخالصی ایجاد می‌کند؛ از این جهت که سبب تغییراتی در دنیای خارج (خارج از میدان دید تابع) می‌شویم. به همین جهت نیاز به روش‌هایی وجود دارد که از این نوع تغییرات جلوگیری کرد:
              // Copy object
              const original = { a: 1, b: 2 };
              const copy = Object.assign({}, original);
              برای تغییری در یک شیء، تنها کافی است خاصیتی را به آن اضافه کنیم و یا با استفاده از واژه‌ی کلیدی delete، خاصیتی را از آن حذف کنیم. به همین جهت برای اینکه تغییرات ما بر روی شیء اصلی اثری را باقی نگذارند، یکی از روش‌ها، استفاده از متد Object.assign است. کار آن، یکی کردن اشیایی است که به آن ارسال می‌شوند. به همین جهت در اینجا با یک شیء خالی، از صفر شروع می‌کنیم. سپس دومین آرگومان آن را به همان شیء مدنظر، تنظیم می‌کنیم. به این ترتیب به یک کپی از شیء اصلی می‌رسیم که دیگر به آن، اتصالی را ندارد. به همین جهت اگر بر روی این شیء کپی تغییراتی را ایجاد کنیم، به شیء اصلی کپی نمی‌شود و سبب تغییرات در آن (mutation) نخواهد شد.
              برای مثال در React، برای انجام رندر نهایی، در پشت صحنه کار مقایسه‌ی اشیاء صورت می‌گیرد. به همین جهت اگر همان شیءای را که ردیابی می‌کند تغییر دهیم، دیگر نمی‌تواند به صورت مؤثری فقط قسمت‌های تغییر کرده‌ی آن‌را تشخیص داده و کار رندر را فقط بر اساس آن‌ها انجام دهد و مجبور خواهد شد کل یک شیء را بارها و بارها رندر کند که اصلا بهینه نیست. به همین جهت، ایجاد تغییرات مستقیم در شیءای که به state آن انتساب داده می‌شود، مجاز نیست.

              متد Object.assign، چندین شیء را نیز می‌تواند با هم یکی کند و شیء جدیدی را تشکیل دهد:
              // Extend object
              const original = { a: 1, b: 2 };
              const extension = { c: 3 };
              const extended = Object.assign({}, original, extension);
              روش دیگر ایجاد یک کپی و یا clone از یک شیء را که پیشتر در سری «React 16x» بررسی کردیم، به کمک امکانات ES-6، به صورت زیر است:
              // Copy object
              const original = { a: 1, b: 2 };
              const copy = { ...original };
              در اینجا نیز ابتدا یک شیء خالی را ایجاد می‌کنیم و سپس توسط spread operator، خواص شیء قبلی را درون آن باز کرده و قرار می‌دهیم. به این ترتیب به یک clone از شیء اصلی می‌رسیم. این حالت نیز از ترکیب چندین شیء با هم، پشتیبانی می‌کند:
              // Extend object
              const original = { a: 1, b: 2 };
              const extension = { c: 3 };
              const extended = { ...original, ...extension };


              روش‌هایی برای جلوگیری از تغییرات در آرایه‌ها در جاوا اسکریپت

              متد slice آرایه‌ها نیز بدون ذکر آرگومانی، یک کپی از آرایه‌ی اصلی را ایجاد می‌کند:
              // Copy array
              const original = [1, 2, 3];
              const copy = [1, 2, 3].slice();
              همچنین معادل همین قطعه کد در ES-6 به همراه spread operator به صورت زیر است:
              // Copy array
              const original = [1, 2, 3];
              const copy = [ ...original ];
              و یا اگر بخواهیم یک کپی از چندین آرایه را ایجاد کنیم می‌توان از متد concat استفاده کرد:
              // Extend array
              const original = [1, 2, 3];
              const extended = original.concat(4);
              const moreExtended = original.concat([4, 5]);
              متد Array.push، هرچند سبب افزوده شدن عنصری به یک آرایه می‌شود، اما یک mutation را نیز ایجاد می‌کند؛ یعنی تغییرات آن به دنیای خارج اعمال می‌گردد. اما Array.concat یک آرایه‌ی کاملا جدید را ایجاد می‌کند و همچنین امکان ترکیب آرایه‌ها را نیز به همراه دارد.
              معادل قطعه کد فوق در ES-6 و به همراه spread operator آن به صورت زیر است:
              // Extend array
              const original = [1, 2, 3];
              const extended = [ ...original, 4 ];
              const moreExtended = [ ...original, ...extended, 5 ];


              مفاهیم ابتدایی Redux


              در Redux برای ایجاد تغییرات در شیء کلی state، از مفهومی به نام dispatch actions استفاده می‌شود. action در اینجا به معنای رخ‌دادن چیزی است؛ مانند کلیک بر روی یک دکمه و یا دریافت اطلاعاتی از یک API. در این حالت مقایسه‌ای بین وضعیت قبلی state و وضعیت فعلی آن صورت می‌گیرد و تغییرات مورد نیاز جهت اعمال به UI، محاسبه خواهند شد.
              اصلی‌ترین جزء Redux، تابعی است به نام Reducer. این تابع، یک تابع خالص است و دو آرگومان را دریافت می‌کند:


              تابع Reducer، بر اساس action و یا رخ‌دادی، ابتدا کل state برنامه را دریافت می‌کند و سپس خروجی آن بر اساس منطق این تابع، یک state جدید خواهد بود. اکنون که این state جدید را داریم، برنامه‌ی React ما می‌تواند به تغییرات آن گوش فرا داده و بر اساس آن، UI را به روز رسانی کند. به این ترتیب کار اصلی مدیریت state، به خارج از برنامه‌ی React منتقل می‌شود.

              در این تصویر، تابع action creator را هم ملاحظه می‌کند که کاملا اختیاری است. یک action می‌تواند یک رشته و یا یک عدد باشد. با پیچیده شدن برنامه، نیاز به ارسال یک‌سری متادیتا و یا اطلاعات بیشتری از اکشن رسیده‌است. کار action creator، ایجاد شیء action، به صورت یک دست و یکنواخت است تا دیگر نیازی به ایجاد دستی آن نباشد.


              مزایای کار با Redux

              - داشتن یک مکان مرکزی برای ذخیره سازی کلی حالت برنامه (به آن «source of truth» و یا store هم گفته می‌شود): به این ترتیب مشکل ارسال خواص در بین کامپوننت‌های عمیق و چند سطحی، برطرف شده و هر زمانیکه نیاز بود، از آن اطلاعاتی را دریافت و یا با قالب خاصی، آن‌را به روز رسانی می‌کنند.
              - رسیدن به به‌روز رسانی‌های قابل پیش بینی state: هرچند در حالت کار با Redux، یک شیء بزرگ جاوا اسکریپتی، کل state برنامه را تشکیل می‌دهد، اما امکان کار مستقیم با آن و تغییرش وجود ندارد. به همین جهت است که برای کار با آن، باید رویدادی را از طریق actionها به تابع Reducer آن تحویل داد. چون Reducer یک تابع خالص است، با دریافت یک سری ورودی مشخص، همواره یک خروجی مشخص را نیز تولید می‌کند. به همین جهت قابلیت ضبط و تکرار را پیدا می‌کند؛ همان بحث serialize و deseriliaze، توسط ابزاری مانند: logrocket. به علاوه قابلیت undo و redo را نیز می‌توان به این ترتیب پیاده سازی کرد (state جدید محاسبه شده، مشخص است، کل state قبلی را نیز داریم یا می‌توان ذخیره کرد و سپس برای undo، آن‌را جایگزین state جدید نمود). افزونه‌ی redux dev tools نیز قابلیت import و export کل state را به همراه دارد.
              - چون تابع Reducer، یک تابع خالص است و همواره خروجی‌های مشخصی را به ازای ورودی‌های مشخصی، تولید می‌کند، آزمایش کردن، پیاده سازی و حتی logging آن نیز ساده‌تر است. در این بین حتی یک افزونه‌ی مخصوص نیز برای دیباگ آن تهیه شده‌است: redux-devtools-extension. تابع خالص، تابعی است که به همراه اثرات جانبی نیست (side effects)؛ به همین جهت عملکرد آن کاملا قابل پیش بینی بوده و آزمون پذیری آن به دلیل نداشتن وابستگی‌های خارجی، بسیار بالا است.


              Context API خود React چطور؟

              در قسمت 33 سری React 16x، مفهوم React Context را بررسی کردیم. پس از معرفی آن با React 16.3، مقالات زیادی منتشر شدند که ... Redux مرده‌است (!) و یا بجای Redux از React context استفاده کنید. اما واقعیت این است که React Redux در پشت صحنه از React context استفاده می‌کند و تابع connect آن دقیقا به همین زیر ساخت متصل می‌شود.
              کار با Redux مزایایی مانند کارآیی بالاتر، با کاهش رندر‌های مجدد کامپوننت‌ها، دیباگ ساده‌تر با افزونه‌های اختصاصی و همچنین سفارشی سازی، مانند نوشتن میان‌افزارها را به همراه دارد. اما شاید واقعا نیازی به تمام این امکانات را هم نداشته باشید؛ اگر هدف، صرفا انتقال ساده‌تر اطلاعات بوده و برنامه‌ی مدنظر نیز کوچک است. React Context برخلاف Redux، نگهدارنده‌ی state نیست و بیشتر هدفش محلی برای ذخیره سازی اطلاعات مورد استفاده‌ی در چندین و چند کامپوننت تو در تو است. هرچند شبیه به Redux می‌توان اشاره‌گرهایی از متدها را به استفاده کنندگان از آن ارسال کرد تا سبب بروز رویدادها و اکشن‌هایی در کامپوننت تامین کننده‌ی Contrext شوند (یا یک کتابخانه‌ی ابتدایی شبیه به Redux را توسط آن تهیه کرد). بنابراین برای انتخاب بین React Context و Redux باید به اندازه‌ی برنامه، تعداد نفرات تیم، آشنایی آن‌ها با مفاهیم Redux دقت داشت.
              مطالب
              روش استفاده‌ی از jQuery در برنامه‌های AngularJS 2.0
              استفاده‌ی گسترده‌ی از jQuery به همراه برنامه‌های AngularJS 2.0 ایده‌ی خوبی نیست؛ زیرا jQuery و کدهای آن، ارتباط تنگاتنگی را بین DOM و JavaScript برقرار می‌کنند که برخلاف رویه‌ی فریم‌ورک‌های MVC است. اما با این حال استفاده‌ی از افزونه‌های بی‌شمار jQuery در برنامه‌های AngularJS 2.0، جهت غنا بخشیدن به ظاهر و همچنین کاربردپذیری برنامه، یکی از استفاده‌های پذیرفته شده‌ی آن است.
              روش استفاده‌ی از jQuery نیز در حالت کلی همانند مطلب «استفاده از کتابخانه‌های ثالث جاوا اسکریپتی در برنامه‌های AngularJS 2.0» است؛ اما به همراه چند نکته‌ی اضافه‌تر مانند محل فراخوانی و دسترسی به DOM، در کدهای یک کامپوننت.


              هدف: استفاده از کتابخانه‌ی Chosen

              می‌خواهیم جهت غنی‌تر کردن ظاهر یک دراپ داون در برنامه‌های AngularJS 2.0، از یک افزونه‌ی بسیار معروف jQuery به نام Chosen استفاده کنیم.


              تامین پیشنیازهای اولیه

              می‌توان فایل‌های این کتابخانه را مستقیما از GitHub دریافت و به پروژه اضافه کرد. اما بهتر است این‌کار را توسط bower مدیریت کنیم. این کتابخانه هنوز دارای بسته‌ی رسمی npm نیست (و بسته‌ی chosen-npm که در مخزن npm وجود دارد، توسط این تیم ایجاد نشده‌است). اما همانطور که در مستندات آن نیز آمده‌است، توسط دستور ذیل نصب می‌شود:
              bower install chosen
              برای مدیریت این مساله در ویژوال استودیو، به منوی project و گزینه‌ی add new item مراجعه کرده و bower را جستجو کنید:


              در اینجا نام پیش فرض bower.json را پذیرفته و سپس محتوای فایل ایجاد شده را به نحو ذیل تغییر دهید:
              {
                  "name": "asp-net-mvc5x-angular2x",
                  "version": "1.0.0",
                  "authors": [
                      "DNT"
                  ],
                  "license": "MIT",
                  "ignore": [
                      "node_modules",
                      "bower_components"
                  ],
                  "dependencies": {
                      "chosen": "1.4.2"
                  },
                  "devDependencies": {
                  }
              }
              ساختار این فایل هم بسیار شبیه‌است به ساختار package.json مربوط به npm. در اینجا کتابخانه‌ی chosen در قسمت لیست وابستگی‌ها اضافه شده‌است. با ذخیره کردن این فایل، کار دریافت خودکار بسته‌های تعریف شده، آغاز می‌شود و یا کلیک راست بر روی فایل bower.json دارای گزینه‌ی restore packages نیز هست.
              پس از دریافت خودکار chosen، بسته‌ی آن‌را در مسیر bower_components\chosen واقع در ریشه‌ی پروژه می‌توانید مشاهده کنید.


              استفاده از jQuery و chosen به صورت untyped

              ساده‌ترین و متداول‌ترین روش استفاده از jQuery و افزونه‌های آن شامل موارد زیر هستند:
              الف) تعریف مداخل مرتبط با آن‌ها در فایل index.html
              <script src="~/node_modules/jquery/dist/jquery.min.js"></script>
              <script src="~/node_modules/bootstrap/dist/js/bootstrap.min.js"></script>
              
              <script src="~/bower_components/chosen/chosen.jquery.min.js"></script>
              <link href="~/bower_components/chosen/chosen.min.css" rel="stylesheet" type="text/css" />
              که در اینجا jQuery و بوت استرپ و chosen به همراه فایل css آن اضافه شده‌اند.
              ب) تعریف jQuery به صورت untyped
              declare var jQuery: any;
              همینقدر که این یک سطر را به ابتدای ماژول خود اضافه کنید، امکان دسترسی به تمام امکانات جی‌کوئری را خواهید یافت. البته بدون intellisense و بررسی نوع‌های پارامترها؛ چون نوع آن، any یا همان حالت پیش فرض جاوا اسکریپت تعریف شده‌است.


              محل صحیح فراخوانی متدهای مرتبط با jQuery

              در تصویر ذیل، چرخه‌ی حیات یک کامپوننت را مشاهده می‌کنید که با تعدادی از آن‌ها پیشتر آشنا شده‌‌ایم:

              روش متداول استفاده از jQuery، فراخوانی آن پس از رخداد document ready است. در اینجا معادل این رخداد، hook ویژ‌ه‌ای به نام ngAfterViewInit است. بنابراین تمام فراخوانی‌های jQuery را باید در این متد انجام داد.
              همچنین جی‌کوئری نیاز دارد تا بداند هم اکنون قرار است با چه المانی کار کنیم و کامپوننت بارگذاری شده کدام است. برای این منظور، یکی از سرویس‌های توکار AngularJS 2.0 را به نام ElementRef، به سازنده‌ی کلاس تزریق می‌کنیم. توسط خاصیت this._el.nativeElement آن می‌توان به المان ریشه‌ی کامپوننت جاری دسترسی یافت.
              constructor(private _el: ElementRef) {
              }


              تهیه‌ی کامپوننت نمایش یک دراپ داون مزین شده با chosen

              در ادامه قصد داریم نکاتی را که تاکنون مرور کردیم، به صورت یک مثال پیاده سازی کنیم. به همین جهت فایل جدید using-jquery-addons.component.ts را به پروژه اضافه کنید به همراه فایل قالب آن به نام using-jquery-addons.component.html؛ با این محتوا:
              الف) کامپوننت using-jquery-addons.component.ts
              import { Component, ElementRef, AfterViewInit } from "@angular/core";
              
              declare var jQuery: any; // untyped
              
              @Component({
                  templateUrl: "app/using-jquery-addons/using-jquery-addons.component.html"
              })
              export class UsingJQueryAddonsComponent implements AfterViewInit {
              
                  dropDownItems = ["First", "Second", "Third"];
                  selectedValue = "Second";
              
                  constructor(private _el: ElementRef) {
                  }
              
                  ngAfterViewInit() {
                      jQuery(this._el.nativeElement)
                          .find("select")
                          .chosen()
                          .on("change", (e, args) => {
                              this.selectedValue = args.selected;
                          });
                  }
              }

              ب) قالب using-jquery-addons.component.html
              <select>
                  <option *ngFor="let item of dropDownItems"
                          [value]="item"
                          [selected]="item == selectedValue">
                      {{item}} option
                  </option>
              </select>
              
              <h4> {{selectedValue}}</h4>
              با این خروجی


              توضیحات

              کلاس UsingJQueryAddonsComponent، اینترفیس AfterViewInit را پیاده سازی کرده‌است؛ تا توسط متد ngAfterViewInit بتوانیم با عناصر DOM کار کنیم. هرچند در کل اینکار باید صرفا محدود شود به مواردی مانند مثال جاری و در حد آغاز یک افزونه‌ی jQuery و اگر قرار است تغییراتی دیگری صورت گیرند بهتر است از همان روش binding توکار AngularJS 2.0 استفاده کرد.
              در سازنده‌ی کلاس، سرویس ElementRef تزریق شده‌است تا توسط خاصیت this._el.nativeElement آن بتوان به المان ریشه‌ی کامپوننت جاری دسترسی یافت. به همین جهت است که پس از آن از متد find، برای یافتن دراپ داون استفاده شده‌است و سپس chosen به نحو متداولی به آن اعمال گردیده‌است.
              در اینجا هر زمانیکه یکی از آیتم‌های دراپ داون انتخاب شوند، مقدار آن به خاصیت selectedValue انتساب داده شده و این انتساب سبب فعال سازی binding و نمایش مقدار آن در ذیل دراپ داون می‌گردد.
              در قالب این کامپوننت هم با استفاده از ngFor، عناصر دراپ داون از آرایه‌ی dropDownItems تعریف شده در کلاس کامپوننت، تامین می‌شوند. متغیر محلی item تعریف شده‌ی در اینجا، در محدودی همین المان قابل دسترسی است. برای مثال از آن جهت تنظیم دومین آیتم لیست به صورت انتخاب شده، در حین اولین بار نمایش view استفاده شده‌است.


              استفاده از jQuery و chosen به صورت typed

              کتابخانه‌ی jQuery در مخزن کد https://github.com/DefinitelyTyped/DefinitelyTyped/tree/master/jquery دارای فایل d.ts. خاص خود است. برای نصب آن می‌توان از روش ذیل استفاده کرد:
              npm install -g typings
              typings install jquery --save --ambient
              پس از افزودن فایل typings این کتابخانه، در ابتدای فایل main.ts یک سطر ذیل را اضافه کنید:
               /// <reference path="../typings/browser/ambient/jquery/index.d.ts" />
              اینکار سبب خواهد شد تا intellisense درون ویژوال استودیو بتواند مداخل متناظر را یافته و راهنمای مناسبی را ارائه دهد.

              در ادامه به فایل using-jquery-addons.component.ts مراجعه کرده و تغییر ذیل را اعمال کنید:
              // declare var jQuery: any; // untyped
              declare var jQuery: JQueryStatic; // typed
              فایل d.ts. اضافه شده، امکان استفاده‌ی از نوع جدید JQueryStatic را مهیا می‌کند. پس از آن در کدهای تعریف شده، chosen به رنگ قرمز در می‌آید، چون در تعاریف نوع دار jQuery، این افزونه وجود خارجی ندارد. برای رفع این مشکل، فایل typings/browser/ambient/jquery/index.d.ts را گشوده و سپس به انتهای آن، تعریف chosen را به صورت دستی اضافه کنید:
              interface JQuery {
                 //...
                 chosen(options?:any):JQuery;
              }
              declare module "jquery" {
                 export = $;
              }
              به این ترتیب این متد به عنوان جزئی از متدهای زنجیروار jQuery، شناسایی شده و قابل استفاده خواهد شد.


              کدهای کامل این پروژه را از اینجا می‌توانید دریافت کنید.
              نظرات مطالب
              ساخت یک Form Generator ساده در MVC
              با سلام و تشکر بابت مطلب مفیدتان
              من برای ساخت پروژه فرم ساز به مسائلی برخورد کردم که به شرح زیر است:
              1- دیتاهای وارد شده به چه صورت در دیتابیس ذخیره شوند؟من ابتدا در نظر داشتم به ازای هر فرمی که کاربر تعریف می‌کند یک جدول در دیتابیس ایجاد کنم  و برای هر کنترلی که در جدول گذاشته می‌شود یک فیلد به جدول فرم اضافه شود.اما با توجه به صحبت شما و روش XML که فرمودید در حال حاضر نمی‌توانم تصمیم گیری کنم که کدام روش بهتر است چون  طبق جستجویی که در نت کردم اگر نیاز به نوشتن کوئری‌های پیچیده بر روی داده‌های وارده شده باشد بهتر است جدول جداگانه ایجاد شود طبق این منبع:
              http://stackoverflow.com/questions/14939973/storing-dynamic-form-and-data-entered-using-json
              پروژه من هم نیاز به ساخت گزارش و داشبورد و BI از روی داده‌های وارد شده است.حال شما کدام انتخاب را انجام می‌دادید؟
              2- نحوه ذخیره طراحی فرم چگونه است؟مثلا اگر در فرم لوگوی شرکت باید قرار گیرد چگونه باشد یا در فرم جدول 3 ستونی باشد که در هر سلول آن یک TextBox قرار می‌گیرد.اندازه هر کنترل  و مقدار پیش فرض   .....
              آیا بهتر نیست اطلاعات کل فرم (شکل ظاهری فعلی فرم بدون داده) را به شکل JSON یا XML یا nvarchar(max)  ذخیره کرد؟
              3- چطوری میتوان Enable  یا Visible بودن یک کنترل را وابسته کرد به مقدار کنترل دیگر در فرم مثلا اگر کمبو سال مالی برابر با 95 بود TextBox درصد سال 95 فعال در غیر اینصورت غیرفعال شود
              ممنون میشم نظر خودتون را بفرمایید
              نظرات مطالب
              فعال سازی و پردازش صفحات پویای افزودن، ویرایش و حذف رکوردهای jqGrid در ASP.NET MVC
              در کد بالا، برای حالت ویرایش یک سلول در نوع select از mvc controller استفاده شده. من کد بالا رو برای webApi میخوام تنظیم کنم. رشته html رو تولید میکنم و پاس میدم به خروجی، اما خطا میده. 
              کد رو ببینید.
               [HttpGet]
              public string SelectAllJqTree()
                      {
                          var result = _kpiTypeService.SelectAll().Select(e => new
                          {
                              value = e.Id,
                              text = e.Name,
                          });
              
                          var select = "<select>{0}</select>";
                          var option = "<option value='{0}' >{1}</option>";
              
                          var options = "";
              
                          foreach (var item in result)
                          {
                              options += string.Format(option, item.value, item.text);
                          }
              
                          return  string.Format(select, options).Trim();
              }
              و در کد js ستون "kpiType" رو هم اینجوری تنظیم کردم:
               colModel: [
                                  {
                                      name: 'KpiTypeID', index: 'KpiTypeID', align: 'right', width: 300,
                                      editable: true, edittype: 'select',
                                      editoptions: {
                                          dataUrl: '/api/KPIType/SelectAllJqTree'
                                      },
                                      editrules: {
                                          required: true
                                      }
                                  }
                            ]
              خروجی این رو با جی کوئری که با صفحه اضافه میکنم، یک کنترل صحیح رو تولید میکنه.
              $.ajax({
                              url: "/api/KPIType/SelectAllJqTree",
                              context: document.body
                          }).done(function (data) {
                              $("#selection").html(data);
                          });

              اما اینجا بهم پیام میده که 
              Uncaught Error: Syntax error, unrecognized expression: "<select><option value='1' >عملکردی</option><option value='2' >بودجه ای</option>
              چه نکته ای وجود داره؟ ایا مربوط به webApi هست؟
              مطالب
              یکسان سازی ی و ک دریافتی حین استفاده از NHibernate


              تصویر فوق، یکی از تصویرهایی است که شاید از طریق ایمیل‌هایی تحت عنوان "فقط در ایران!" به دست شما هم رسیده باشد. تصور کاربر نهایی (که این ایمیل را با تعجب ارسال کرده) این است که در اینجا به او گفته شده مثلا "مرتضی" را جستجو نکنید و امثال آن. چون برای او تفاوتی بین ی و ی وجود ندارد. همچنین بکار بردن "اقلامی" هم کمی غلط انداز است و بیشتر ذهن را به سمت کلمه سوق می‌دهد تا حرف.

              در ادامه‌ی بحث آلرژی مزمن به وجود انواع "ی" و "ک" در بانک اطلاعاتی (+ و + و +)، اینبار قصد داریم این اطلاعات را به NHibernate بسط دهیم. شاید یک روش اعمال یک دست سازی "ی" و "ک" این باشد که در کل برنامه هر جایی که قرار است update یا insert ایی صورت گیرد، خواص رشته‌ای را یافته و تغییر دهیم. این روش "کار می‌کنه" ولی ایده آل نیست؛ چون حجم کار تکراری در برنامه زیاد خواهد شد و نگهداری آن هم مشکل می‌شود. همچنین امکان فراموش کردن اعمال آن هم وجود دارد.
              در NHibernate یک سری EventListener وجود دارند که کارشان گوش فرا دادن به یک سری رخدادها مانند مثلا update یا insert است. این رخدادها می‌توانند پیش یا پس از هرگونه ثبت یا ویرایشی در برنامه صادر شوند. بنابراین بهترین جایی که جهت اعمال این نوع ممیزی (Auditing) بدون بالا بردن حجم برنامه یا اضافه کردن بیش از حد یک سری کد تکراری در حین کار با NHibernate می‌توان یافت، روال‌های مدیریت کننده‌ی همین EventListener ها هستند.

              کلاس YeKeAuditorEventListener نهایی با پیاده سازی IPreInsertEventListener و IPreUpdateEventListenerبه شکل زیر خواهد بود:
              using NHibernate.Event;

              namespace NHYeKeAuditor
              {
              public class YeKeAuditorEventListener : IPreInsertEventListener, IPreUpdateEventListener
              {
              // Represents a pre-insert event, which occurs just prior to performing the
              // insert of an entity into the database.
              public bool OnPreInsert(PreInsertEvent preInsertEvent)
              {
              var entity = preInsertEvent.Entity;
              CorrectYeKe.ApplyCorrectYeKe(entity);
              return false;
              }

              // Represents a pre-update event, which occurs just prior to performing the
              // update of an entity in the database.
              public bool OnPreUpdate(PreUpdateEvent preUpdateEvent)
              {
              var entity = preUpdateEvent.Entity;
              CorrectYeKe.ApplyCorrectYeKe(entity);
              return false;
              }
              }
              }
              در کدهای فوق روال‌های OnPreInsert و OnPreUpdate پیش از ثبت و ویرایش اطلاعات فراخوانی می‌شوند (همواره و بدون نیاز به نگرانی از فراموش شدن فراخوانی کدهای مربوطه). اینجا است که فرصت داریم تا تغییرات مورد نظر خود را جهت یکسان سازی "ی" و "ک" دریافتی اعمال کنیم (کد کلاس CorrectYeKe را در پیوست خواهید یافت).

              تا اینجا فقط تعریف YeKeAuditorEventListener انجام شده است. اما NHibernate چگونه از وجود آن مطلع خواهد شد؟
              برای تزریق کلاس YeKeAuditorEventListener به تنظیمات برنامه باید به شکل زیر عمل کرد:
              using System;
              using System.Linq;
              using FluentNHibernate.Cfg;
              using NHibernate.Cfg;

              namespace NHYeKeAuditor
              {
              public static class MappingsConfiguration
              {
              public static FluentConfiguration InjectYeKeAuditorEventListener(this FluentConfiguration fc)
              {
              return fc.ExposeConfiguration(configListeners());
              }

              private static Action<Configuration> configListeners()
              {
              return
              c =>
              {
              var listener = new YeKeAuditorEventListener();
              c.EventListeners.PreInsertEventListeners =
              c.EventListeners.PreInsertEventListeners
              .Concat(new[] { listener })
              .ToArray();
              c.EventListeners.PreUpdateEventListeners =
              c.EventListeners.PreUpdateEventListeners
              .Concat(new[] { listener })
              .ToArray();
              };
              }
              }
              }
              به این معنا که FluentConfiguration خود را همانند قبل ایجاد کنید. درست در زمان پایان کار تنها کافی است متد InjectYeKeAuditorEventListener فوق بر روی آن اعمال گردد و بس (یعنی پیش از فراخوانی BuildSessionFactory).

              کدهای NHYeKeAuditor را از اینجا می‌توانید دریافت کنید.