مطالب
مرتب سازی صحیح حروف فارسی در بانک اطلاعاتی SQLite
فرض کنید لیست حروف الفبای فارسی را در یک بانک اطلاعاتی SQLite ذخیره کرده‌اید:
var connection = new SqliteConnection("Data Source=:memory:");
connection.Open();

var createCommand = connection.CreateCommand();
createCommand.CommandText =
            @"
                CREATE TABLE persian_letter (
                    value TEXT
                );

                INSERT INTO persian_letter
                VALUES ('ا'),('ب'),('پ'),('ت'),('ث'),('ج'),('چ'),('ح'),('خ'),('د'),('ذ'),('ر'),('ز'),('ژ'),('س'),('ش'),
                       ('ص'),('ض'),('ط'),('ظ'),('ع'),('غ'),('ف'),('ق'),('ک'),('گ'),('ل'),('م'),('ن'),('و'),('ه'),('ی');
            ";
createCommand.ExecuteNonQuery();
اگر از این لیست کوئری گرفته و آن‌ها‌را مرتب کنیم:
var queryCommand = connection.CreateCommand();
queryCommand.CommandText =
            @"
                SELECT value
                FROM persian_letter
                order by value
            ";
var reader = queryCommand.ExecuteReader();
var sortedDbItems = new List<string>();
while (reader.Read())
{
    sortedDbItems.Add($"{reader["value"]}");
}
یک چنین خروجی حاصل می‌شود:


همانطور که ملاحظه می‌کنید، مرتب سازی حروف فارسی در اینجا به صورت پیش‌فرض کار نمی‌کند. علت اینجا است که روش پیش‌فرض مرتب سازی حروف در SQLite، بر اساس کد اسکی حروف است و فقط در مورد حروف ASCII از A تا Z درست کار می‌کند.


امکان تعریف Collation سفارشی در SQLite

در بانک‌های اطلاعاتی، قابلیتی که مستقیما بر روی نحوه‌ی جستجو و همچنین مرتب سازی حروف تاثیر می‌گذارد، Collation نام دارد و در SQLite برخلاف بسیاری از بانک‌های اطلاعاتی دیگر، امکان تعریف Collation سفارشی نیز وجود دارد و برای این منظور باید یک function pointer را در اختیار آن قرار داد تا از آن در سمت بانک اطلاعاتی جهت مرتب سازی و جستجوی حروف استفاده کند.
خوشبختانه پروژه‌ی Microsoft.Data.Sqlite امکان تبدیل یک managed delegate دات نتی را به یک function pointer مخصوص SQLite، میسر می‌کند. به عبارتی SQLite کدهای دات نتی را در حین انجام محاسبات خود اجرا خواهد کرد و این اجرا به صورتی نیست که ابتدا کل اطلاعات، به سمت برنامه‌ی کلاینت منتقل شود و سپس در این سمت، در حافظه، عملیاتی بر روی آن صورت گیرد. کل عملیات در سمت بانک اطلاعاتی مدیریت می‌شود.
روش تعریف یک Collation جدید هم در اینجا بسیار ساده‌است:
connection.CreateCollation("PersianCollationNoCase", (x, y) => string.Compare(x, y, ignoreCase: true));
فقط کافی است بر روی اتصال باز شده، متد CreateCollation فراخوانی و نحوه‌ی مقایسه‌ی دو رشته مشخص شود. سپس این Collation نامدار، به صورت زیر در کوئری‌ها قابل استفاده خواهد بود:
SELECT value
FROM persian_letter
order by value COLLATE PersianCollationNoCase
اینبار اگر خروجی برنامه را بررسی کنیم، مشاهده خواهیم کرد که مرتب سازی حروف فارسی در SQLite به درستی کار می‌کند:



تعریف Collation سفارشی غیرحساس به «ی و ک» !

این مورد شاید یکی از آرزوهای توسعه دهندگان SQL Server باشد! اما با SQLite به سادگی زیر قابل تعریف و مدیریت است:
connection.CreateCollation("PersianCollationNoCaseYekeInsensitive",
(x, y) => string.Compare(x.ApplyCorrectYeKe(), y.ApplyCorrectYeKe(), ignoreCase: true));
متد ApplyCorrectYeKe فوق از بسته‌ی نیوگت DNTPersianUtils.Core دریافت شده و کار آن یک‌دست کردن «ی و ک» فارسی و عربی است.
در یک چنین حالتی اگر اطلاعاتی را به همراه «ی و ک» فارسی و یا عربی ثبت کنیم:
CREATE TABLE persian_letter (
value TEXT
);
INSERT INTO persian_letter
VALUES ('ی'),('ک');
جستجوی بر روی آن‌ها دیگر وابسته‌ی به مقدار «ی و ک» وارد شده نبوده و چه «ی و ک» فارسی وارد شود و چه عربی، این کوئری همواره کار می‌کند:
SELECT count()
FROM persian_letter
WHERE value = 'ی' COLLATE PersianCollationNoCaseYekeInsensitive


کدهای کامل این مثال را از اینجا می‌توانید دریافت کنید: SQLitePersianCollation.zip
مطالب
بارگذاری بدون وقفه فایل‌های جاوااسکریپت به کمک async و defer
امروزه در برنامه‌های تحت وب، بارگذاری فایل‌های جاوااسکریپت صفحات، یکی از چالش‌های بزرگ در عملکرد، کارآیی و سرعت اجرای صفحات وب به شمار می‌‌آید. حال اینکه توسعه اپلیکیشن‌های single page و استفاده از کتابخانه‌های حجیم جاوااسکریپتی، حجم این سری فایل‌ها را بیشتر و بیشتر نیز می‌کند.

در شرایطی خاص، تگ script باعث می‌شود که مرورگر برای مدت زمانی متوقف شود و فایل‌های جاوااسکریپت را بارگذاری و اجرا نماید. در این مواقع مرورگر از انجام عملیات دیگری منع شده و شروع به اعمال فایل جاوااسکریپت در حال بارگذاری در محتوای صفحه‌ی بار شده می‌کند. این نگارش و اعمال می‌تواند سبب ویرایش یک element و یا تغییر DOM یا ارجاعی به یک URL دیگر شود. به این منظور، بهترین و رایج‌ترین کار این است که تگ‌های script را به انتهای صفحه و پیش از تگ body منتقل کنیم. با این حال نیز ممکن است که مرورگر برای چند ثانیه منتظر دریافت پاسخ‌های اسکریپت‌های انتهای صفحه بماند، اما این امر چندان قابل توجه نیست؛ به این دلیل که غالب استایل‌ها و content صفحه بارگذاری شده‌اند. با این وجود، این راهکار برای صفحات وب کنونی که ممکن است شامل محتوای یک یا چندین مگابایتی باشند، کافی نیست.  
در این مواقع برخی از کد نویس‌ها از روش‌هایی مانند inject کردن تگ script به صورت Ajax استفاده می‌کنند که این روش‌ها از block شدن صفحه جلوگیری می‌کند، اما با این حال این روش‌ها نیز چالش‌های خاص خود مانند نوشتن کد‌های اضافی برای هر اسکریپت و تست‌های مرتبط برای اطمینان از بار شدن و اجرای صحیح اسکریپت‌ها در موقعیت مناسب را دارند که ممکن است روند کد نویسی با استفاده از کتابخانه‌های third-party را بسیار طولانی کند.
برای حل این چالش خرسندم که تکنیکی را که به صورت built-in در HTML5 وجود دارد، به شما معرفی کنم.

استفاده از defer Attribute

 این Attribute اگر درون هر تگ script ایی نوشته شود، آن فایل در هنگام بارگذاری فایل‌ها و ساختن صفحه، نادیده گرفته می‌شود و پس از اتمام پروسه، این فایل شروع به بارگذاری شدن می‌کند. در حقیقت در این حین در مرورگر همانند تمامی عملیات‌های Lazy Loading به صورت ضمنی یک promise ساخته می‌شود. البته گفتنی است که این نوع بارگذاری نباید شامل فایل‌های جاوا اسکریپتی باشد که شامل عملیاتی مانند document.write و یا تغییرات DOM هستند.
<script src="file.js" defer></script>
مرورگر تمامی فایل‌های شامل defer Attribute را بدون توقف پردازش‌های صفحه، به صورت موازی بارگذاری می‌نماید. اما اینکه این ویژگی از چه زمانی در مرورگر‌ها وجود داشته؟ باید گفت که تقریبا 12 سال از عمر آن می‌گذرد. تقریبا از نسخه‌ی IE4 ( ^_^ ). البته این نکته گفتنی است هنگامی که شما از این Attribute استفاده می‌کنید، این تضمین وجود دارد که تمامی این اسکریپت‌ها اجرا می‌شوند، اما اینکه کدامیک در چه زمانی بارگذاری و اجرا می‌شوند، کاملا نامشخص است. از نظر تئوری، عملیات بارگذاری پس از ویرایش DOM و کمی پیش از فراخوانی رخداد DOMContentLodaded صورت می‌گیرد. اما در عمل، این عملیات به مرورگر و سیستم‌عامل نیز وابسته است.

استفاده از async Attribute

این Attribute در HTML5 معرفی شد و به نوعی کامل کننده و منسوخ کننده‌ی defer می‌باشد.
<script src="file.js" async></script>
به طور کلی می‌توان گفت که عملکرد async و defer یکسان می‌باشند. البته تفاوت اصلی این دو سینتکس، در زمان اجرای اسکریپت‌های بار شده می‌باشد. در async عملیات execution، در اولین فرصتی که پس از تکمیل دریافت فایل ممکن است، صورت می‌گیرد. به سه تصویر زیر توجه کنید:

تصویر فوق یک سناریوی ساده‌ی بارگذاری صفحه‌ی html را به همراه یک فایل جاوااسکریپت با تگ script ساده را نمایش می‌دهد. همانطور که ملاحظه می‌کنید، در لحظه‌ای که فایل اسکریپت شروع به دانلود شدن می‌کند (قسمت بنفش)، عملیات parse صفحه متوقف شده تا زمانی که فایل دانلود و اجرا شود (قسمت قرمز). پس از آن دوباره عملیات parsing از سر گرفته می‌شود. این عملیات به همراه تگ script ساده صورت گرفته است. حال در تصویر بعد قصد داریم که همین سناریو را به کمک defer Attribute بررسی کنیم:

همانطور که ملاحظه می‌کنید به کمک defer، شروع عملیات دانلود فایل اسکریپت، خللی در عملیات html parse ایجاد نمی‌کند و این دو عملیات به صورت موازی می‌توانند اجرا شوند. پس از دریافت فایل اسکریپت، این فایل مستقیما اجرا نمی‌شود و لزوما باید پس از عملیات parsing صورت پذیرد.

و اما تصویر زیر، سناریو‌ی فوق را به همراه async attribute نمایش می‌دهد:

در این حالت عملیات دریافت فایل اسکریپت همانند defer به صورت موازی اجرا می‌شود. اما تفاوتی که در این قسمت و در async وجود دارد، زمان اجرا شدن فایل‌های اسکریپت است. همانطور که ملاحظه می‌کنید دقیقا پس از دریافت فایل، اسکریپت ما در اجراست و پس از اجرای کامل، دوباره عملیات parsing ادامه می‌یابد. در حقیقت اسکریپت‌های با async attribute با فراخوانی رخداد onload شروع به اجرا می‌کنند. جهت استفاده‌ی از async، خیالتان راحت باشد؛ با توجه به این منبع، تقریبا تمام مرورگرها از این ویژگی پشتیبانی می‌کنند.

نظرات مطالب
پایان پروژه ASP.NET Ajax Control Toolkit !
@farbod
برای کلا جاوا اسکریپت هم کتابخانه‌های Unit test وجود دارد تا از این دلچرکین بودن خارج شوید:
QUnit

@محمد امین شریفی
اینبار انتخاب مایکروسافت درست بوده:
1- هزینه توسعه رو کاهش دادند. برای مثال هدف از Ajax Control Toolkit چیزی بوده شبیه به پلاگین‌های jQUery اما با هزینه بیشتر. اینبار شما هزاران پلاگین جی کوئری در اختیارتون هست و نه صرفا مجموعه‌ی Ajax Control Toolkit .
2- موردی رو که در مقاله بالا بهش اشاره شده و دلیل اصلی کنار گذاشتن ASP.NET Ajax بوده پایین بودن کارآیی ASP.NET Ajax است. هم حجم بالایی دارد و هم تبادلات شبکه‌ای حجیمی را به همراه دارد که در هر دو مورد جی کوئری بهینه‌تر است.
و یک سری موارد دیگر که قبلا بهش اشاره کرده بودم: (+)
3- انتخاب اصلی کتابخانه Ajax در ASP.NET MVC الان همین جی‌کوئری است و در مقاله فوق به یک سری افزونه و کتابخانه کمکی برای آن اشاره شده (که در حال توسعه و تکمیل است).
مطالب
آشنایی با ساختار IIS قسمت ششم
در مطلب قبلی روش دستی را برای اضافه کردن ماژول‌های خود، نام بردیم. در اینجا به روش‌های دیگر اضافه کردن ماژول‌ها می‌پردازیم.

استفاده از محیط گرافیکی IIS جهت لیست کردن، اضافه و حذف ماژول‌ها

به بخش modules درIIS بروید. در پنل سمت راست همه امکانات جهت افزودن و ویرایش و حذف وجود دارند:


روش معرفی ماژول در خط فرمان با استفاده از دستور Appcmd

 Appcmd.exe install module   /name:MODULE_NAME /image:PATH_TO_DLL

قسمت name که نام ماژول است  و قسمت image هم مسیر قرار گرفتن فایل dll هست.

برای نمونه:

%windir%\system32\inetsrv\appcmd.exe install module /name:DefaultDocumentModule /image:%windir%\system32\inetsrv\defdoc.dll

در صورتیکه ماژولی که قبلا افزوده شده باشد را بخواهید اضافه کنید، خطای زیر را دریافت خواهید کرد:

ERROR ( message:Failed to add duplicate collection element "DefaultDocumentModule". )

جهت حذف ماژول دستور زیر را صادر کنید:

Appcmd.exe uninstall module MODULE_NAME

نمونه:

%windir%\system32\inetsrv\appcmd.exe uninstall module DefaultDocumentModule

گرفتن کوئری یا لیستی از ماژول‌های فعال برای یک اپلیکیشن یا عمومی:

Appcmd.exe list modules [/app.name:APPLICATION_NAME]

سوپپچ aap.name اختیاری است ولی اگر نام یک اپلیکیشن را به آن بدهید، فقط ماژول‌هایی را که روی این اپلیکیشن اجرا می‌شوند، لیست می‌کند.

نمونه:

%windir%\system32\inetsrv\appcmd.exe list modules /app.name:"Default Web Site"

کد زیر هم نمونه ای برای لیست کردن تمامی ماژول‌های عمومی که بر روی تمامی اپلیکیشن‌ها اجرا می‌شوند:

%windir%\system32\inetsrv\appcmd.exe list modules

خط زیر یک ماژول را برای همه اپلیکیشن‌ها یا اپلیکیشن خاصی فعال می‌کند که بستگی دارد سوییچ type چگونه مقداردهی شده باشد:

Appcmd.exe add module /name:MODULE_NAME /type:MGD_TYPE

برای مثال خط زیر باعث می‌شود ماژول Forms Authentication فقط برای وب اپلیکیشن default web site فعال شود:

%windir%\system32\inetsrv\appcmd.exe add module /name:FormsAuthentication /type:System.Web.Security.FormsAuthenticationModule /app.name:"Default Web Site"

یا در پایین آن را به صورت عمومی یا global فعال می‌کند:

%windir%\system32\inetsrv\appcmd.exe add module /name:FormsAuthentication /type:System.Web.Security.FormsAuthenticationModule

برای غیرفعال کردن یک ماژول از دستور زیر استفاده می‌شود:

Appcmd.exe delete module MODULE_NAME [/app.name:APPLICATION_NAME]

اگر غیر فعال کردن یک ماژول در یک اپلیکیشن خاص مدنظر شما باشد دستور زیر نمونه آن است:

%windir%\system32\inetsrv\appcmd.exe delete module FormsAuthentication /app.name:"Default Web Site"

اگر قصد دارید آن‌را بر روی تمامی اپلیکیشن‌ها غیرفعال کنید، دستور زیر نمونه آن است:

%windir%\system32\inetsrv\appcmd.exe delete module FormsAuthentication

حفظ کردن یا به خاطر سپردن دستورات بالا ممکن است کار سخت و دشواری باشد، به همین جهت از help کمک بگیرید:

Appcmd.exe module /?

یا به شکل اختصاصی‌تر برای یک دستور

Appcmd.exe install module /?Appcmd add module /?
نظرات اشتراک‌ها
زبان برنامه نویسی Erlang
NodeJS یک فریم ورک سمت سرور بر پایه زبان جاوا اسکرپیت می‌باشد. قبلا جاوا اسکریپت فقط توسط مفسرهای مرورگرهای وب تفسیر می‌شد (یعنی فقط می‌تونستیم باهاش کدهای سمت کاربر بنویسیم)، اما حالا با NodeJs می‌تونید کدنویسی سمت سرور کنید. از طرفی چون با جاوا اسکریپت کدنویسی می‌کنید قابلیت استقلال از پلتفرم رو براتون به ارمغان میاره. ارتباط بین سرور و کلاینت موقعی که از NodeJs در طرف سرور استفاده می‌کنید دو طرفه هست، بدین معنی که علاوه بر اینکه کلاینت می‌تونه به سرور درخواست بده بعد سرور به درخواست اون پاسخ بده، سرور هم می‌تونه بدون داده شدن یک درخواست توسط کلاینت داده ای رو به طرف کلاینت ارسال کنه.

زبان Erlang در سال 1986 توسط شرکت Ericson سوئد به منظور استفاده در سرور‌های switching تلفن ساخته شد. این زبان توسط تیمی به سرپرستی  Joe Armstrong معرفی شد تا بتواند از برنامه‌های توزیع‌شده، مقاوم در برابر خطا، بلادرنگ و بی‌وقفه پشتیبانی کند. بعدها این زبان به شکل متن‌باز در اختیار عموم قرار گرفت. یکی از روش‌های برنامه نویسی که توسط این برنامه میشه ازش استفاده کرد، روش تابعی (Functional Programming) هست. این روش قبلا وجود داشت و مدتی هم از مد افتاد، ولی با اومدن پردازنده‌های چند هسته ای استفاده از زبان‌های برنامه نویسی که میشه با اونها تابعی نوشت از سر گرفته شد و حتی مایکروسافت در سال 2010 زبان برنامه نویسی #F رو معرفی کرد. یکی از قابلیتهای زبانهای تابعی سرعت اجرا شدن کدهای اونها هست که اونها رو از زبانهای امری مثل #C و Java جدا می‌کنه.

Scala هم یک زبان برنامه نویسی همه منظوره هست که ویژگی هایی رو از زبان‌های برنامه نویسی شیء گرا داره و همچنین توسط اون میشه برنامه نویسی تابعی انجام داد. از اون به عنوان جانشینی برای جاوا یاد می‌کنند چون قابلتهای اضافه بر جاوا رو داره.
اشتراک‌ها
با پلیمر احساس متفاوتی از طراحی المان های وب داشته باشید

شرکت گوگل جدیدا محصولی به نام Polymer ارائه کرده است که میتواند برای نوسع دهندگان وب مفید و لذتبخش باشد. این طراحی همانند sdk می‌باشد که با آن میتوانید کنترل‌های اختصاصی‌تری بسازید و المان‌های پیش فرض جالبی دارد.

با پلیمر احساس متفاوتی از طراحی المان های وب داشته باشید
نظرات اشتراک‌ها
تبدیلگر ایران سیستم به یونیکد
در متد get_Unicode_To_IranSystem  نوع لیست اشتباه است، من به جای آن List<byte> نوشتم. این لیست رو چطور میشه به string تبدیل کرد؟
مطالب
شروع کار با Apache Cordova در ویژوال استودیو #3
در قسمت قبل توانستیم ابزارهای لازم را برای Apache Cordova، نصب کنیم. در این قسمت یک پروژه‌ی ساده را ایجاد کرده و در مورد ساختار آن توضیح خواهم داد. در ادامه‌ی مقالات از  AngularJS ، Bootstrap ,Typescript و jQuery Mobile  هم در پروژه‌ها استفاده خوهیم کرد.
برای شروع، از قسمت JavaScript یا Typescript، یک پروژه‌ی از نوع Blank App ایجاد کنید. به شکل زیر:


ترجیحا نوع Typescript را انتخاب کردم. البته در داخل فایل ts. امکان نوشتن جاوا اسکریپت هم هست. بعد از ایجاد پروژه اگر با تصویری شبیه به تصویر زیر روبرو شدید، در نتیجه تنظیمات نصب و راه اندازی به درستی صورت گرفته است.



اگر به قسمت solution explorer دقت کنید، فایلی به نام config.xml را مشاهده خواهید کرد. با کلیک بر روی این فایل، یک صفحه‌ی گرافیکی باز خواهد شد که این امکان را به شما می‌دهد که پلاگین‌های مورد نیاز خود، تنظیمات مربوط به نرم افزار تولیدی (مانند تنظیم ورژن ویندوزی که می‌خواهید app شما بر روی آن اجرا شود) و تنظیمات مربوط به هر یک از پلتفرم‌ها را به صورت مجزا در اختیار داشته باشید.



یک فایل index.html هم در قالب پیش‌فرض قرار داده شده که بعدا می‌توانید آن را تغییر دهید و یا صفحات دیگری را اضافه کنید. همان طور که در قسمت‌های قبل گفته شد، قرار است ما یک وب اپلیکیشن طراحی کنیم و آن را درون Container بومی Cordova بسته بندی کنیم. لذا محدودیتی برای استفاده‌ی از کتابخانه‌های مرتبط با CSS ، HTML و JavaScript  نداریم و در ادامه‌ی مقالات با مثال‌های متعددی از آن‌ها استفاده خواهیم کرد.

در فولدر scripts-->typeings-->cordova-->plugins  اینترفیس‌هایی که برای دسترسی به امکانات بومی دستگاه تلفن فعلا در Cordova پشتیبانی می‌شوند، قرار گرفته است.

برای استفاده از تکنولوژی‌های وب در محیط بومی دستگاه، در طی فرآیند کامپایل، Cordova یک اپلیکیشن را به وسیله دو چیز مهم که در زیر اشاره شده است، خواهد ساخت.


  • یک اپلیکیشن با یک کامپوننت  WebView که با مرورگر یکپارچه شده است.
  • یه سری از منابعی که در داخل فایل‌های اپلیکیشن وب ما قرار دارند.


برای یکپارچه شدن API‌های Cordova با وب پیج موجود، اندکی کد نیاز داریم که برای انکار لینکی شبیه لینک زیر را در فایل html خود استفاده می‌کنیم که فقط بعد از کامپایل وجود خارجی دارد؛ به صورت زیر:

<script src="cordova.js"></script>

در پایان هم برای فهمیدن اینکه API‌های Cordova در دسترس هستند، می‌توانیم رخداد مربوط به devicerady را مدیریت کنیم؛ به صورت زیر:

document.addEventListener("deviceready", onDeviceReady, false);
function onDeviceReady() { /* INIT */ }

برای مدیریت رخدادهای مربوط به pause و resume هم که نشان دهنده‌ی ادامه برنامه (خارج شدن از حالت pause) و حالت تعلیق هستند، می‌توان به شکل زیر عمل کرد:

 function onDeviceReady() {
            // Handle the Cordova pause and resume events
            document.addEventListener('pause', onPause, false);
            document.addEventListener('resume', onResume, false);

            // TODO: Cordova has been loaded. Perform any initialization that requires Cordova here.
        }

        function onPause() {
            // TODO: This application has been suspended. Save application state here.
        }

        function onResume() {
            // TODO: This application has been reactivated. Restore application state here.
        } 

حال قصد داریم پروژه‌ی خود را که قرار است یک متن ساده را نشان دهد، با استفاده از شبیه ساز اجر ا کنیم. برای این منظور از قسمت toolbar ویژوال استودیو ، Solution Platform خود را انتخاب کنید و سپس می‌توانید شبیه ساز مورد نظر خود را انتخاب کرده و برنامه را اجرا کنید. در اینجا محیط مورد نظر من اندروید است  و برای این منظور هم میتوانم از شبیه ساز Android Emulator یا Ripple استفاده کنم.  به دلیل سرعت کم شبیه ساز اندروید، می‌توانید شبیه ساز  YouWave را دانلود و اجرا کرده و در قسمتی که شبیه ساز را از toolbar ویژوال انتخاب می‌کردید، این بار گزینه‌ی Device را انتخاب کنید. بعد از کامپایل برنامه‌ی شما، فایل apk تولید شده بر روی شبیه ساز نصب خواهد شد و شما قادر خواهید بود آنرا اجرا کنید.

نتیجه‌ی نهایی 

 با شبیه ساز Ripple 


مطالعه بیشتر

https://msdn.microsoft.com/en-us/library/dn879821(v=vs.140).aspx 

http://blog.falafel.com/getting-started-with-cordova-and-multi-device-hybrid-app-in-visual-studio/ 

http://www.codeproject.com/Articles/860150/Visual-Studio-and-Apache-Cordova 


نکته : وقتی پروژه را برای اولین بار اجرا می‌کنید شاید کمی طول بکشد تا نتیجه‌ی نهایی را ببنید و آن هم به دلیل این است که ویژوال استودیو  باید مجموعه‌ای از package  های مورد نیاز Cordova را دانلود کند.

در مقاله بعد با jQuery Mobile آشنا خواهیم شد و یک مثال برای کار کردن با آن در نظر خواهم گرفت.


ادامه دارد ...