مطالب
خواندنی‌ها روز 22 فروردین

سایت iplocationtools بانک اطلاعاتی موقعیت مکانی IP های خود را که ماهیانه نیز به روز خواهد شد، به رایگان برای دریافت قرار داده است. فرمت تعاریف جداول و عبارت insert آن مطابق دستورات بانک اطلاعاتی MySQL است.
تنها بازیگر شاخص یازده سال قبل در زمینه توسعه برنامه‌های مبتنی بر QT ، برنامه KDevelop بوده است. این وضعیت با ارائه Qt Creator‌ بهبود یافته است ...
  • شرکت Red gate که پیشتر برنامه‌ی معروف Reflector را در جهت اهداف تبلیغاتی خود تصاحب کرده بود، اکنون در ادامه‌ی همین سیاست، کتاب Illustrated C# 2008 را نیز به رایگان ارائه داده است.
  • سایت DelphiFeeds.com با طراحی جدید خود چند روزی است که متحول شده است. سایتی شبیه به سایت مهندس خودمان که بعد از عید معلوم نیست چه بلایی سرش آمده است و جای خالی آن احساس می‌شود، هر چند سایت IDevCenter نیز همین کار را به صورت تخصصی‌تری ارائه می‌دهد.
  • Microsoft MED-V 1.0 در جهت توسعه‌ی اهداف مجازی سازی مایکروسافت ارائه شد.

مطالب
Debugger visualizers

از VS.Net 2005 به بعد، امکانات اشکال زدایی کدها به شدت بهبود یافته و یکی از امکانات جالبی که به آن اضافه شده است، Debugger visualizers می‌باشد، یعنی امکان مشاهده‌ی محتوای اشیاء در حین دیباگ. همچنین با استفاده از SDK ویژوال استودیو، برنامه نویس‌ها می‌توانند Debugger visualizers سفارشی خودشان را نیز تهیه کنند. در ادامه به تعدادی از این موارد اشاره خواهد شد:
  • Xml Visualizer v.2 - site
  • Data Debugger Visualizer - site
  • WCF Visualizers Tool - site
  • IL Visualizer - site
  • DB Connection Visualizer - site
  • LINQ to SQL Debug Visualizer - site
  • Graphics Debugger Visualizer - site
  • Bitmap Debugger Visualizer - site
  • PowerShell Debug Visualizer - site
  • WebVisualizers - site
  • Sharepoint debug visualizer - site
  • WPF Tree Debugger Visualizer - site
  • GUID Debugger Visualizer - site
  • WindowsIdentity Debugger Visualizer - site
  • ControlTree visualizer - site
  • Regular Expression Visualizers - site
  • Improving Visual C++ Debugging - site

نظرات نظرسنجی‌ها
کدام یک از بسته های کامپوننت را در زمینه WPF بیشتر می پسندید؟چرا؟
یک گزینه‌ی «هیچکدام» را هم اگر اضافه می‌کردید، بهتر می‌شد. چون WPF هدفش حذف این بسته‌های کامپوننت است و به شخصه تا به امروز فقط از یک سری template تغییر رنگ و شکل ظاهری کنترل‌های استاندارد آن، از مورد دیگری استفاده نکرده‌ام. یعنی واقعا نیازی نیست. تمام کنترل‌های آن قابلیت سفارشی سازی کامل را دارند و همچنین اندکی هم جستجو کنید تمام آن‌ها را با مثال‌های فراوانی می‌توانید پیدا کنید. این بسته‌های کامپوننت هم در کل چیزی نیستند به جز جمع آوری این مقالات و نظم دادن به آن‌ها. یک نمونه‌ی آن «Extended WPF Toolkit™ Community Edition » هست.
نظرات مطالب
آموزش Knockout.Js #2
ممنون دوست عزیز.
بله امکان پذیر است. باید از المان‌های تودرتو استفاده کنیم. به این صورت که المان ریشه با استفاده از with به model مربوطه مقید می‌شود و المان‌های داخلی به خواص مدل bind می‌شوند. برای مثال:
<div data-bind="text: teacher"> </div>//مقید سازی به مدل اول
<p data-bind="with: student">//مقید سازی المان ریشه به مدل دوم
    Name: <span data-bind="text: name"> </span>,//مقید سازی خواص به المان‌های داخلی
    Family: <span data-bind="text: family"> </span>
</p>
 
<script type="text/javascript">
    ko.applyBindings({
        teacher: "myTeacher",
        student: {
            name:  "Masoud",
            family: "Pakdel" 
       }
    });
</script>
مطالب
Cookie - قسمت سوم

Cookie - قسمت اول: مقدمه، تاریخچه، معرفی، و شرح کامل

Cookie - قسمت دوم: کوکی در جاوا اسکریپت

نکته مهم: خواندن قسمت‌های قبلی این سری (مخصوصا قسمت اول) برای درک بهتر مطالب پیشنهاد می‌شود.



کوکی در ASP.NET - بخش اول

در قسمت‌های قبلی مقدمات و مباحث کلی راجع به کوکی‌ها و انواع آن، شرح کامل خواص، نحوه رفتار مرورگرها با انواع کوکی‌ها و درنهایت نحوه کار کردن با کوکی‌ها در سمت کلاینت با استفاده از زبان محبوب جاوا اسکریپت پرداخته شد.

در ادامه این سری مطالب به نحوه برخورد ASP.NET با کوکی‌ها و چگونگی کار کردن با کوکی در سمت سرور آشنا خواهیم شد. در بخش اول این قسمت مباحث ابتدایی و اولیه برای کار با کوکی‌ها در ASP.NET ارائه می‌شود. در بخش دوم مباحث پیشرفته‌تر همچون SubCookieها در ASP.NET و نیز سایر نکات ریز کار با کوکی‌ها در ASP.NET بحث خواهد شد.

.


Response و Request در ASP.NET

در قسمت اول این سری به مفاهیم Http Response و Http Request اشاره کوتاهی شده بود. به‌صورت خلاصه، درخواستی که از سمت یک کلاینت به یک وب سرور ارسال می‌شود Request و پاسخی که وب سرور به آن درخواست می‌دهد Response نامیده می‌شود.

در ASP.NET، کلیه اطلاعات مرتبط با درخواست رسیده از سمت یک کلاینت در نمونه‌ای منحصر به فرد از کلاس HttpRequest نگه‌داری می‌شود. محل اصلی نگه‌داری این نمونه در پراپرتی Request از نمونه جاری کلاس System.Web.HttpContext (قابل دسترسی ازطریق HttpContext.Current) است. البته کلاس Page هم یک پراپرتی با نام Request دارد که دقیقا از همین پراپرتی کلاس HttpContext استفاده می‌کند.

هم‌چنین کلیه اطلاعات مرتبط با پاسخ ارسالی وب سرور به سمت کلاینت مربوطه در نمونه‌ای از کلاس HttpResponse ذخیره می‌شود. محل اصلی نگه‌داری این نمونه نیز در پراپرتی Response از نمونه جاری کلاس HttpContext است. همانند Request، کلاس Page یک پراپرتی با نام Response برای نگه‌داری این نمونه دارد که این هم دقیقا از پراپرتی متناظر در کلاس HttpContext استفاده می‌کند.



کوکی‌ها در Response و Request

هر دو کلاس HttpResponse و HttpRequest یک پراپرتی با عنوان Cookies (^ و ^) دارند که مخصوص نگهداری کوکی‌های مربوطه هستند. این پراپرتی از نوع System.Web.HttpCookieCollection است که یک کالکشن مخصوص برای ذخیره کوکی‌هاست.

- این پراپرتی (Cookies) در کلاس HttpRequest محل نگه‌داری کوکی‌های ارسالی توسط مرورگر در درخواست متناظر آن است. کوکی‌هایی که مرورگر با توجه به شرایط جاری و تنظیمات کوکی‌ها اجازه ارسال به سمت سرور را به آن‌ها داده و در درخواست ارسالی ضمیمه کرده است (با استفاده از هدر :Cookie که در قسمت اول شرح داده شد) و ASP.NET پس از پردازش و Parse داده‌ها، درون این پراپرتی اضافه کرده است.

- این پراپرتی (Cookies) در کلاس HttpResponse محل ذخیره کوکی‌های ارسالی از وب سرور به سمت مرورگر کلاینت در پاسخ به درخواست متناظر است. کوکی‌های درون این پراپرتی پس از بررسی و استخراج داده‌های موردنیاز توسط ASP.NET در هدر پاسخ ارسالی ضمیمه خواهند شد (با استفاده از هدر :Set-Cookie که در قسمت اول توضیح داده شد).

.


ایجاد و به‌روزرسانی کوکی در ASP.NET

برای ایجاد یک کوکی و ارسال آن به سمت کلاینت همان‌طور که در بالا نیز اشاره شد، باید از پراپرتی Response.Cookies از کلاس HttpContext استفاده کرد. برای ایجاد یک کوکی روش‌های مختلفی وجود دارد.

  • در روش اول با استفاده از ویژگی مخصوص ایندکسر کلاس HttpCookieCollection عملیات تولید کوکی انجام می‌شود. در این روش، ابتدا بررسی می‌شود که کوکی موردنظر در لیست کوکی‌های جاری وجود دارد یا خیر. درصورتی‌که با این نام قبلا یک کوکی ثبت شده باشد، مقدار کوکی موجود بروزرسانی خواهد شد. اما اگر این نام وجود نداشته باشد یک کوکی جدید با این نام به لیست افزوده شده و مقدار آن ثبت می‌شود. مثال:
HttpContext.Current.Response.Cookies["myCookie"].Value = "myCookieValue";
  • روش بعدی استفاده از متد Add در کلاس HttpCookieCollection است. در این روش ابتدا یک نمونه از کلاس HttpCookie ایجاد شده و سپس این نمونه به لیست کوکی‌ها اضافه می‌شود. کد زیر چگونگی استفاده از این روش را نشان می‌دهد:
var myCookie = new HttpCookie("myCookie", "myCookieValue");
HttpContext.Current.Response.Cookies.Add(myCookie);
  • روش دیگر استفاده از متد Set کلاس HttpCookieCollection است. تفاوت این متد با متد Add در این است که متد Set ابتدا سعی می‌کند عملیات update انجام دهد. یعنی عملیات افزودن تنها وقتی‌که نام کوکی موردنظر در لیست کوکی‌ها یافته نشود انجام خواهد شد. برای مثال:
HttpContext.Current.Response.Cookies.Set(new HttpCookie("myCookie", "myCookieValue"));

نکته: باتوجه به توضیحات بالا، متد Set اجازه افزودن دو کوکی با یک نام را نمی‌دهد. برای اینکار باید از متد Add استفاده کرد. درباره این موضوع در قسمت بعدی بیشتر توضیح داده خواهد شد.

  • روش دیگری که برای ایجاد یکی کوکی می‌توان از آن استفاده کرد، بکارگیری متد AppnedCookie از کلاس HttpResponse است. در این روش نیز ابتدا باید یک نمونه از کلاس HttpCookie تولید شود. این روش همانند استفاده از متد Add از کلاس HttpCookieCollection است. کد زیر مثالی از این روش را نشان می‌دهد:

HttpContext.Current.Response.AppendCookie(new HttpCookie("myCookie", "myCookieValue"));
  • روش بعدی استفاده از متد SetCookie از کلاس HttpResponse است. فرق این متد با متد AppendCookie در این است که در متد SetCookie ابتدا وجود یک کوکی با نام ارائه شده بررسی می‌شود و درصورت وجود، مقدار این کوکی بروزرسانی می‌شود. درصورتی‌که قبلا یک کوکی با این نام وجود نداشته باشد، یک کوکی جدید به لیست کوکی‌ها اضافه می‌شود. این روش همانند استفاده از متد Set از کلاس HttpCookieCollection است. نمونه‌ای از نحوه استفاده از این متد در زیر آورده شده است:
HttpContext.Current.Response.SetCookie(new HttpCookie("myCookie", "myCookieValue"));

نکته: تمامی فرایندهای نشان داده شده در بالا تنها موجب تغییر محتویات کالکشن کوکی‌ها درون HttpContext می‌شود و تا زمانی‌که توسط وب سرور با استفاده از دستور Set-Cookie به سمت مرورگر ارسال نشوند تغییری در کلاینت بوجود نخواهند آورد.

برای آشنایی بیشتر با این روند کد زیر را برای تعریف یک کوکی جدید درنظر بگیرید:

HttpContext.Current.Response.Cookies["myCookie"].Value = "myValue";
برای مشاهده هدر تولیدی توسط وب سرور می‌توان از نرم افزار محبوب Fiddler استفاده کرد (از اواخر سال 2012 که نویسنده این ابزار به Telerik پیوسته، توسعه آن بسیار فعال‌تر شده و نسخه‌های جدید با لوگوی جدید! ارائه شده است).
تصویر زیر مربوط به مثال بالاست:

همانطور که مشاهده می‌کنید دستور ایجاد یک کوکی با نام و مقدار وارده در هدر پاسخ تولیدی توسط وب سرور گنجانیده شده است.

نکته: در ASP.NET به صورت پیش فرض از مقدار "/" برای پراپرتی Path استفاده می‌شود.


خواص کوکی در ASP.NET

برای تعیین یا تغییر خواص یک کوکی در ASP.NET باید به نمونه HttpCookie مربوطه دست یافت. سپس با استفاده از پراپرتی‌های این کلاس می‌توان خواص موردنظر را تعیین کرد. برای مثال:

var myCookie = new HttpCookie(string.Empty);
myCookie.Name = "myCookie";
myCookie.Value = "myCookieValue";
myCookie.Domain = "dotnettip.info";
myCookie.Path = "/post";
myCookie.Expires = new DateTime(2015, 1, 1);
myCookie.Secure = true;
myCookie.HttpOnly = true;

نکته مهم: امکان تغییر خواص یک کوکی به صورت مستقیم در سمت سرور وجود ندارد. درواقع برای اعمال این تغییرات در سمت کلاینت باید به ازای هر کوکی موردنظر یک کوکی جدید با مقادیر جدید ایجاد و به کالکشن کوکی‌ها در Http Response مربوطه اضافه شود تا پس از قرار دادن دستور Set-Cookie متناظر در هدر پاسخ ارسالی به سمت کلاینت و اجرای آن توسط مرورگر، مقادیر خواص مورنظر در سمت کلاینت بروزرسانی شوند. دقت کنید که تمامی نکات مرتبط با هویت یک کوکی که در قسمت اول شرح داده شد در اینجا نیز کاملا صادق است.

روش دیگری نیز برای تعیین برخی خواص کوکی‌ها به صورت کلی در فایل وب کانفیگ وجود دارد. برای اینکار از تگ httpCookies در قسمت system.web استفاده می‌شود. برای مثال:

<httpCookies domain="www.example.com" httpOnlyCookies="true" requireSSL="true" />

این امکان از ASP.NET 2.0 به بعد اضافه شده است. با استفاده از این تگ، تنظیمات اعمال شده برای تمامی کوکی‌ها درنظر گرفته می‌شود. البته درصورتی‌که تنظیم موردنظر برای کوکی به صورت صریح آورده نشده باشد. برای نمونه به کد زیر دقت کنید:

var myCookie = new HttpCookie("myCookie", "myCookieValue");
myCookie.Domain = "test.com";
HttpContext.Current.Response.Cookies.Add(myCookie);
var myCookie2 = new HttpCookie("myCookie2", "myCookieValue2");
myCookie2.HttpOnly = false;
myCookie2.Secure = false;
HttpContext.Current.Response.Cookies.Add(myCookie2);

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

همان‌طور که می‌بینید تنها مقادیر پراپرتی‌هایی که صراحتا برای کوکی آورده نشده است از تنظیمات وب کانفیگ خوانده می‌شود.

. 


حذف کوکی در ASP.NET

برای حذف یک کوکی در ASP.NET یک روش کلی وجود دارد که در قسمت‌های قبلی نیز شرح داده شده است، یعنی تغییر خاصیت Expires کوکی به تاریخی در گذشته. برای نمونه داریم:

var myCookie = new HttpCookie("myCookie", "myCookieValue");
myCookie.Expires = DateTime.Now.AddYears(-1);

نکته مهم: در کلاس HttpCookieCollection یک متد با نام Remove وجود دارد. از این متد برای حذف یک کوکی از لیست موجود در این کلاس استفاده می‌شود. دقت کنید که حذف یک کوکی از لیست کوکی‌ها با استفاده از این متد تاثیری بر موجودیت آن کوکی در سمت کلاینت نخواهد گذاشت و تنها روش موجود برای حذف یک کوکی در سمت کلاینت همان تنظیم مقدار خاصیت Expires است.


خواندن کوکی در ASP.NET

برای خواندن مقدار یک کوکی ارسالی از مرورگر کلاینت در ASP.NET، باتوجه به توضیحات ابتدای این مطلب، طبیعی است که باید از پراپرتی Request.Cookies در نمونه جاری از کلاس HttpContext استفاده کرد. برای این کار نیز چند روش وجود دارد.

  • روش اول استفاده از ایندکسر کلاس HttpCookieCollection است. برای اینکار نیاز به نام یا ایندکس کوکی موردنظر در لیست مربوطه داریم. برای مثال:
var myCookie = HttpContext.Current.Request.Cookies["myCookie"];
  • یا این نمونه با استفاده از ایندکسر عددی:
var myCookie = HttpContext.Current.Request.Cookies[0];
  • روش دیگری که برای خواند مقدار یک کوکی می‌توان بکار برد، استفاده از متد Get از کلاس HttpCookieCollection است. این متد همانند ایندکسر این کلاس نیاز به نام یا ایندکس کوکی موردنظر دارد. برای نمونه:
var myCookie = HttpContext.Current.Request.Cookies.Get("myCookie");
var myCookie = HttpContext.Current.Request.Cookies.Get(0);

.


بحث و نتیجه گیری

تا اینجا با مفاهیم اولیه درباره نحوه برخورد ASP.NET با کوکی‌ها آشنا شدیم. روش‌های مختلف ایجاد و یا به‌روزرسانی کوکی‌ها نشان داده شد. با تعیین انواع خواص کوکی‌ها آشنا شدیم. نحوه حذف یک کوکی در ASP.NET را دیدیم. روش‌های خواندن مقادیر کوکی‌ها را نیز مشاهده کردیم.

باز هم تاکید می‌کنم که تمامی تغییرات اعمالی در سمت سرور تا زمانی‌که به‌صورت دستورات Set-Cookie در هدر پاسخ وب سرور قرار نگیرند هیچ کاری در سمت کلاینت انجام نمی‌دهند.

در قسمت بعدی این سری مطالب به مباحث پیشرفته‌تری چون SubCookieها در ASP.NET و هویت منحصر به فرد کوکی‌ها در سمت سرور پرداخته می‌شود.



منابع

http://msdn.microsoft.com/en-us/library/ms178194(v=vs.100).aspx

http://msdn.microsoft.com/en-us/library/aa289495(v=vs.71).aspx

http://www.codeproject.com/Articles/31914/Beginner-s-Guide-To-ASP-NET-Cookies

http://www.codeproject.com/Articles/244904/Cookies-in-ASP-NET
مطالب
آموزش Knockout.Js #4
مقید سازی رویداد کلیک
Click Binding روشی است برای اضافه کردن یک گرداننده رویداد در زمانی که قصد داریم یک تابع جاوااسکریپتی را در هنگام کلیک بر روی المان مورد نظر فراخوانی کنیم. از این مقید سازی عموما در عناصر button و input و تگ a استفاده می‌شود. اما در حقیقت در تمام عناصر غیر پنهان صفحه مورد استفاده قرار می‌گیرد.
<div>
    Number Of Clicks <span data-bind="text: numberOfClicks"></span> times
    <button data-bind="click: clickMe">Click me</button>
</div>
 
<script type="text/javascript">
    var viewModel = {
        numberOfClicks : ko.observable(0),
        clickMe: function() {
            var previousCount = this.numberOfClicks();
            this.numberOfClicks(previousCount + 1);
        }
    };
</script>
رویداد کلیک  button در کد بالا به تابعی با نام clickMe مقید شده است. این تابع در viewModel جاری صفحه تعریف شده است و در بدنه آن تعداد کلیک‌های قبلی را به علاوه یک خواهد کرد. از آنجا که تگ span در بالای صفحه به تعداد کلیک‌ها مقید شده است در نتیجه همواره مقدار این تگ به روز خواهد بود.

*نکته اول: اگر قصد داشته باشیم که عنصر جاری در viewModel را به گرداننده رویداد پاس دهیم چه باید کرد؟
هنگام فراخوانی رویدادها، KO به صورت پیش فرض مقدار جاری مدل را به عنوان اولین پارامتر به این گرداننده پاس می‌دهد. این روش مخصوصا در هنگامی که قصد اجرای عملیاتی خاص بر روی تک تک عناصر یک مجموعه را داشته باشید(مثل حلقه foreach) بسیار مفید خواهد بود.
<ul data-bind="foreach: places">
    <li>
        <span data-bind="text: $data"></span>
        <button data-bind="click: $parent.removePlace">Remove</button>
    </li>
</ul>
 
 <script type="text/javascript">
     function MyViewModel() {
         var self = this;
         self.places = ko.observableArray(['Tehran', 'Esfahan', 'Shiraz']);
 
         self.removePlace = function(place) {
             self.places.remove(place)
         }
     }
     ko.applyBindings(new MyViewModel());
</script>
در تابع removePlace می‌بینید که مقدار آیتم جاری در لیست به عنوان اولین آرگومان به این تابع پاس داده می‌شود، در نتیجه می‌دانیم که کدام عنصر را باید از لیست مورد نظر حذف کنیم. برای به دست آوردن آیتم جاری در لیست از parent$ یا root$ می‌توان استفاده کرد.
همان طور که پست قبل توضیح داده شد؛ برای اینکه بتوانیم از یک viewModel به مجموعه از عناصر در  یک حلقه foreach مقید کنیم امکان استفاده از اشاره گر this میسر نیست. در نتیجه بهتر است در ابتدای viewModel مقدار این اشاره گر را در یک متغیر معمولی (در اینجا به نام self است) ذخیره کنیم و از این پس این متغیر را برای اشاره به عناصر viewModel به کار بریم. در اینجا self به عنواتن یک alias برای this خواهد بود.

*نکته دوم: دسترسی به عنصر رویداد
در بعضی مواقع نیاز است در حین فراخوانی رویداد ،عنصر رویداد DOM  به عنوان فرستنده در اختیار تابع گرداننده قرار گیرد. خبر خوش این است که KO به صورت پیش فرض این عنصر را نیز به عنوان پارامتر دوم به توابع گرداننده رویداد پاس می‌دهد. برای مثال:
<button data-bind="click: myFunction">
    Click me
</button>
 
 <script type="text/javascript">
    var viewModel = {
        myFunction: function(data, event) {
            if (event.shiftKey) {
               
            } else {               
            }
        }
    };
    ko.applyBindings(viewModel);
</script>
تابع myFunction در مثال بالا دارای دو پارامتر است. پارامتر دوم در این تابع به عنوان عنصر فرستنده رویداد مورد استفاده قرار خواهد گرفت. بدین ترتیب در توابع event Handler‌ها می‌توان به راحتی اطلاعات مورد نیاز درباره آبجکت رویداد را به دست آورد.

*نکته سوم: به صورت پیش فرض KO از اجرای عملیات پیش فرض رویداد‌ها جلوگیری به عمل می‌آورد. این به این معنی است که اگر برای رویداد کلیک تگ a بک تابع گرداننده تعریف کرده باشید، بعد از کلیک بر روی این المان؛ مرورگر فقط این تابع تعریف شده توسط شما را فراخوانی خواهد کرد و دیگر عملیات راهبری به صفحه مورد نظر در خاصیت href صورت نخواهد گرفت. اگر به هر دلیلی قصد داشته باشیم که این رفتار صورت نگیرد کافیست در انتهای تابع گرداننده رویداد مقدار true برگشت داده شود.

*نکته چهارم: مفهوم clickBubble
ابتدا به کد زیر دقت کنید:
<div data-bind="click: myDivHandler">
    <button data-bind="click: myButtonHandler">
        Click me
    </button>
</div>
همان طور که مشاهده می‌کنید در کد بالا برای عنصر button یک رویداد کلید تعریف شده است. از طرف دیگر این button درون تگ div قرار دارد که برای این تگ نیز این رویداد کلیک با تابع گرداننده متفاوتی تعریف شده است. نکته این جاست که به صورت پیش فرض بعد از فراخوانی رویداد کلیک عنصر داخلی، رویداد کلیک عنصر خارجی نیز فراخوانی خواهد شد. به این رفتار event bubbling می‌گویند. اگر قصد داشته باشیم که این رفتار را غیر فعال کنیم(بعنی با کلیک بر روی button، رویداد کلیک تگ div اجرا نشود باید مقدار خاصبت clickBubble رویداد عنصر داخلی را برابر false قرار دهیم) به صورت زیر:
<div data-bind="click: myDivHandler">
    <button data-bind="click: myButtonHandler, clickBubble: false">
        Click me
    </button>
</div>
مطالب
پلاگین جستجو با jquery و twitter bootstrap
در این مطلب با نحوه استفاده از پلاگین جستجوی سفارشی searchboxmvc.js آشنا خواهید شد. 

قبلاً در اینجا با نحوه ایجاد پلاگین jQuey آشنا شدید. روشی دیگری نیز برای ایجاد این نوع پلاگین‌ها وجود دارد و آن استفاده از widget factory موجود در پلاگین jQuery UI می‌باشد. 
برای استفاده از این پلاگین که کدهای کامل آن در فایل پیوست موجود است، ابتدا باید فایل‌های لازم را به پروژه خود اضافه کنیم:
    <link rel="stylesheet" href="@Url.Content("~/Content/bootstrap-rtl.css")" type="text/css" />
    <script type="text/javascript" src="@Url.Content("~/scripts/jquery-2.0.2.min.js")"></script>
    <script type="text/javascript" src="@Url.Content("~/scripts/jquery-ui-1.10.3.min.js")"></script>
    <script type="text/javascript" src="@Url.Content("~/scripts/bootstrap-rtl.js")"></script>
    <script type="text/javascript" src="@Url.Content("~/scripts/searchboxmvc.js")"></script>
سپس در کنترلر خود یک Action بصورت زیر ایجاد کنید:
 [HttpPost]
        public virtual ActionResult LoadData(string fieldName, string value, string stringFilterMode = "startWith")
        {
            Thread.Sleep(2000);
            var models = MakePersons();
            if (fieldName == "Id")
            {
                models = models.Where(p => p.Id == int.Parse(value)).Take(1).ToList();
            }
            else if (fieldName == "FirstName")
            {
                models = models.Where(p => p.FirstName.StartsWith(value)).ToList();
            }

            return Json(new { Status = "OK", Records = models });
        }
        private List<Person> MakePersons()
        {
            var lst = new List<Person>();
            lst.Add(new Person() { Id = 1, Code = "Uytffs-098", FirstName = "احمدرضا", LastName = "عابدزاده" });
            lst.Add(new Person() { Id = 2, Code = "fTuuuw-652", FirstName = "کریم", LastName = "باقری" });
            lst.Add(new Person() { Id = 3, Code = "Lopapo-123", FirstName = "خداداد", LastName = "عزیزی" });
            lst.Add(new Person() { Id = 4, Code = "Utppq-981", FirstName = "علی", LastName = "دایی" });
            lst.Add(new Person() { Id = 5, Code = "zttsn-471", FirstName = "علی", LastName = "کریمی" });
            lst.Add(new Person() { Id = 6, Code = "poiud-901", FirstName = "مهدی", LastName = "مهدوی کیا" });
            lst.Add(new Person() { Id = 7, Code = "wqrPoP-391", FirstName = "علیرضا", LastName = "منصوریان" });
            return lst;
        }
در ادامه در ویوی مورد نظر خود یک div ایجاد کنید. همین div خام با اعمال پلاگین بر روی آن ، بصورت یک پلاگین جستجو عمل خواهد کرد.
حال کدهای جاوا اسکریپت مورد نظر را برای اعمال پلاگین و تنظیمات موردنیاز آن به div ایجاد شده می‌نویسیم:
...
<div id="div_SearchBoxContainer">
</div>
...
@section scripts{
    <script type="text/javascript">
        $("#div_SearchBoxContainer").searchboxmvc({
            loadUrl: '@Url.Action(actionName: "LoadData", controllerName: "Home")',
            defaultStringFilterMode: "startWith",
            loadDataOnLeave: true,
            displayClass: "",
            displayNoResultClass: "",
            display: function (element, record) {
                $(element).html(record.FirstName + "  " + record.LastName);
            },
            listItemsDisplay: function (element, record, index) {
                return record.LastName + " " + record.FirstName + "(" + record.Code + ")";
            },
            fields: [
                {
                    fieldName: "Id",
                    fieldTitle: "شناسه",
                    width: 100,
                    defaultValueField: true
                },
                {
                    fieldName: "FirstName",
                    fieldTitle: "نام",
                    width: 200,
                    defaultDisplayField: true,
                    filter: true,
                    isStringType: true
                },
                {
                    fieldName: "LastName",
                    fieldTitle: "نام خانوادگی",
                    filter: false,
                    isStringType: true
                }
            ]
        });
    </script>
}

شرح پارامترهای افزونه searchboxmvc.js 
loadUrl : آدرس اکشن متدی است که بصورت ajax ای فراخوانی شده و نتایج حاصل را بازگشت میدهد.
 نتایج حاصله باید با فرمت json بازگشت داده شوند. اگر نتایج موفقیت باشد باید بصورت  ({Json(new { Status = "OK", Records = models بازگشت داده شوند و اگر خطایی در این بین صورت گرفت مقدار Status نباید مقدار OK باشد.
پارامترهای مورد نیاز این اکشن نیز باید به ترتیب با نام های fieldName و value باشند که fieldName نام فیلدی است که جستجو بر اساس آن صورت می‌گیرد و value همان مقدار وارد شده توسط کاربر است. 
defaultStringFilterMode : اگر فیلد مورد جستجو از نوع رشته ای باشد (یعنی isStringType  آن برابر true باشد) آنگاه پارامتر سوم اکشن متد بطور خودکار مقداردهی خواهد شد. مقادیر این خاصیت میتواند startWith  یا contains و یا equal باشد.
loadDataOnLeave : اگر برابر false باشد، هربار که متن input تغییر کرد بلافاصله یک تقاضا برای یافتن مقادیر به سرور فرستاده میشود و نیازی نیست که فوکوس از کنترل خارج شود.
displayClass : نام کلاس css است که به div 3 اعمال خواهد شد.
displayNoResultClass : در صورتیکه جستجو نتیجه ای نداشته باشد این کلاس به div 3 اعمال خواهد شد.
display : یک فانکشن که برای ایجاد خروجی html برای نمایش در div 3 بکار می‌رود.
listItemsDisplay : یک فانکشن که برای ایجاد خروجی html برای آیتم‌ها بکار می‌رود.
fields : یک آرایه از فیلدهای موردنیاز پلاگین .
خاصیت‌های فیلد نیز بصورت زیر است:
fieldName : نام فیلد
fieldTitle : عنوان فیلد
defaultValueField : فیلد پیش فرض که جستجو بر اساس آن صورت می‌گیرد. اگر تعیین نشود فیلد اول آرایه به عنوان فیلد پیش فرض انتخاب خواهد شد.
defaultDisplayField : فیلد پیش فرض که برای نمایش متن div 3 بکار می‌رود(البته اگر پارامتر display تعیین نشود)
filter : اگر برابر true باشد این فیلد در لیست فیلدهای جستجو خواهد آمد و کاربر می‌تواند بر اساس آن جستجو انجام دهد.
isStringType : اگر برابر true باشد ، پارامتر سوم اکشن متد بطور خودکار مقداردهی خواهد شد.
لازم به ذکر است که این پلاگین کامل نیست و فقط برای ارائه مثال اینجا آورده شده است. هر یک از دوستان می‌توانند محتوای پلاگین را به سلیقه خود تغییر داده و پلاگین را کاملتر کنند.
sample_mvc.zip
نظرات مطالب
تنظیمات تاریخ قمری در ویندوز
یک نکته‌ی تکمیلی
برای اینکه تنظیمات ذکر شده در مورد تقویم قمری تاثیر داده شوند، تقویم انتخابی باید به صورت ذیل باشد:
new CultureInfo("ar-SA") { DateTimeFormat = { Calendar = new HijriCalendar() } }
مطالب
توسعه کنترلر و مدل در F# MVC4
در پست قبلی با F# MVC4 Template آشنا شدید. در این پست به توسعه کنترلر و مدل در قالب مثال خواهم پرداخت. برای شروع ابتدا یک پروژه همانند مثال ذکر شده در پست قبلی ایجاد کنید. در پروژه #C ساخته شده که صرفا برای مدیریت View‌ها است یک View جدید به صورت زیر ایجاد نمایید:
@model IEnumerable<FsWeb.Models.Book>
<!DOCTYPE html>
<html>
<head>
    <title>@ViewBag.Title</title>
    <meta name="viewport" content="width=device-width, initial-scale=1" />
    <link rel="stylesheet" 
        href="http://code.jquery.com/mobile/1.0.1/jquery.mobile-1.0.1.min.css" />
</head>
 
<body>
    <div data-role="page" data-theme="a" id="booksPage">
        <div data-role="header">
            <h1>Guitars</h1>
        </div>
        <div data-role="content">
        <ul data-role="listview" data-filter="true" data-inset="true"> 
            @foreach(var x in Model) {
                <li><a href="#">@x.Name</a></li>
            }
        </ul>
        </div>
    </div>
    <script src="http://code.jquery.com/jquery-1.6.4.min.js">
    </script>
    <script src="http://code.jquery.com/mobile/1.0.1/jquery.mobile-1.0.1.min.js">
    </script>

    <script>
        $(document).delegate("#bookPage", 'pageshow', function (event) {
            $("div:jqmData(role='content') > ul").listview('refresh');
        });
    </script>
</body>
</html>
از آنجا که هدف از این پست آشنایی با بخش #F پروژه‌های وب است در نتیجه نیازی به توضیح کد‌های بالا دیده نمی‌شود. 
برای ساخت کنترلر جدید، در پروژه #F ساخته شده یک Source File ایجاد نمایید و کد‌های زیر را در آن کپی نمایید:
namespace FsWeb.Controllers

open System.Web.Mvc
open FsWeb.Models

[<HandleError>]
type BooksController() =
    inherit Controller()
    member this.Index () =   
        seq { yield  Book(Name = "My F# Book")
              yield Book(Name = "My C# Book") }
        |> this.View
در کد‌های بالا ابتدا یک کنترلر به نام BookController ایجاد کردیم که از کلاس Controller ارث برده است(با استفاده از inherit).  سپس یک تابع به نام Index داریم(به عنوان Action مورد نظر در کنترلر) که آرایه ای از کتاب‌ها به عنوان پارامتر به تابع View می‌فرستد.( توسط اپراتور Pipe - <|). در نهایت دستور this.View  معادل فراخوانی اکشن ()View در پروژه‌های #C است که View متناظر با اکشن را فراخوانی می‌کند. همان طور که ملاحظه می‌نمایید بسیار شبیه به پیاده سازی #C است.
اما نکته ای که در مثال بالا وجود دارد این است که دو نمونه از نوع Book را برای ساخت seq وهله سازی می‌کند. در نتیجه باید Book Type را به عنوان مدل تعریف کنیم. به صورت زیر:
namespace FsWeb.Models
 type Book = { Id : Guid; Name : string }
البته در F# 3.0 امکانی فراهم شده است به نام Auto-Properties که شبیه تعریف خواص در #C است. در نتیجه می‌توان تعریف بالا را به صورت زیر نیز بازنویسی کرد:
namespace FsWeb.Models 
type Book() = member val Name = "" with get, set
Attribute‌ها مدل
اگر همچون پروژه‌های #C قصد دارید با استفاده از Attribute‌ها مدل خود را اعتبارسنجی نمایید می‌توانید به صورت زیر اقدام نمایید:
open System.ComponentModel.DataAnnotations
 type Book() = [<Required>] member val Name = "" with get, set
هم چنین می‌توان Attribute‌های مورد نظر برای مدل EntityFramework را نیز اعمال نمود(نظیر Key):
namespace FsWeb.Models 
open System 
open System.ComponentModel.DataAnnotations 
type Book() = [<Key>] member val Id = Guid.NewGuid() with get, set 
[<Required>] member val Name = "" with get, set

نکته: دستور open معادل با using در #C است.
در پست بعدی برای تکمیل مثال جاری، روش طراحی Repository با استفاده از EntityFramework بررسی خواهد شد.
مطالب
برنامه نویسی پیشرفته JavaScript - قسمت 5 - معرفی برخی عملگرها

معرفی برخی عملگرها

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


عملگر typeof

از آنجائیکه جاوا اسکریپت دارای نوع داده‌ای ضعیف یا Loosely Typed می‌باشد، باید در بکارگیری متغیرها و یا آرگومانهای ورودی توابع، دقت لازم را داشته باشیم تا خطایی در اجرای کد یا محاسبات به وجود نیاید. بنابراین به راهکارهایی نیاز داریم تا بتوانیم نوع داده‌ای یک متغیر را تشخیص دهیم و قبل از بکارگیری آنها صحت و اعتبار داده‌های ورودی را بررسی کنیم. با استفاده از عملگر typeof می‌توانیم نوع داده‌ای یک متغیر را تشخیص دهیم که برای هر نوع داده‌ای مقادیر زیر را بر میگرداند:

· برای متغیرهایی که شامل مقدار undefined می‌باشند مقدار "undefined"

· برای متغیرهای منطقی یا Boolean مقدار "boolean"

· برای متغیرهای رشته‌ای یا String مقدار "string"

· برای متغیرهای عددی و مقادیر NaN و Infinity مقدار "number"

· برای تابع مقدار "function"

· برای اشیا و مقادیر null مقدار "object"

var x;
var n = 12;
var obj = {};
var fn = function () { };
var a = new Array();

alert(typeof x);        // "undefined"
alert(typeof n);        // "number"
alert(typeof obj);     // "object"
alert(typeof fn);       // "function"
alert(typeof a);        // "object"

عملگر instanceof

عملگر typeof بهترین روش جهت تشخیص نوع داده‌ای متغیرهایی است که دارای نوع داده‌ای پایه یا Primitive Type هستند. اما جهت تشخیص نوع داده‌ای اشیاء و به صورت کلی انواع ارجاعی، این عملگر فقط مقدار "object" را برمیگرداند و اشاره‌ای به ماهیت واقعی آن Object ندارد. برای این منظور می‌توانیم از عملگر instanceof استفاده نماییم تا بررسی کنیم یک نوع ارجاعی از جنس چه نوع Object ی می‌باشد. شکل کلی استفاده از این عملگر به صورت زیر است:

result = variable instanceof constructor

اگر variable ، از جنس نوع ارجاعی تعیین شده در بخش سازنده یا constructor باشد، عملگر instanceof مقدار true را بر می‌گرداند. به مثال زیر توجه کنید:

var a = new Array();
alert(a instanceof Array); // true
alert(a instanceof Object);   // true
alert(a instanceof Date); // false
توجه داشته باشید که اگر عملگر instanceof برای یک نوع ارجاعی به کار رود و با سازنده Object بررسی شود، همیشه مقدار true برمی گرداند.

عملگر in

همانطور که قبلا اشاره شد، جهت دسترسی به اعضای یک شیء، می‌توان با آن شیء همانند یک آرایه رفتار نمود. به عبارتی دیگر میتوان نام یک ویژگی یا تابع را در [] قرار داد تا به مقدار آن دسترسی داشت. بنابراین می‌توان همانند یک آرایه و با استفاده از یک حلقه‌ی for-in تمامی اعضای یک شیء را پیمایش نمود. در واقع عملگر in در این حلقه بررسی می‌کند چه ویژگی‌ها و توابعی در یک شیء وجود دارند و تمامی آنها را بر می‌گرداند. به مثال زیر توجه کنید:

var person = {
    name: "Meysam",
    age: 33,
    sayInfo: function () {
        alert(name + ":" + age);
    }
};

for (var i in person) 
    alert(i + " => " + person[i]);

خروجی :

     name => Meysam

    age => 33

    sayInfo => function() {
        alert(name + ":" + age);
    }
در مثال فوق، توسط حلقه‌ی for-in ، شیء person را پیمایش نمودیم. در این پیمایش، متغیر i ، به تک تک اعضای موجود در این شیء اشاره می‌کند. بنابراین متغیر i شامل نام ویژگی یا تابع می‌باشد و person[i] مقدار موجود در آن ویژگی یا محتوای تابع را بر میگرداند.

کاربرد دیگر عملگر in بررسی وجود یک ویژگی یا تابع در یک شیء می‌باشد. اگر ویژگی یا تابع مورد نظر در شیء وجود داشته باشد، مقدار true را  بر می‌گرداند. به مثال زیر توجه کنید:

alert("name" in person); // true
alert("sayInfo" in person); // true
alert("birth" in person); // false


عملگر delete

از عملگر delete جهت حذف یک ویژگی و یا یک تابع از یک شیء استفاده می‌شود. به مثال زیر توجه کنید:

var person = {
    name: "Meysam",
    age: 33,
    sayInfo: function () {
        alert(name + ":" + age);
    }
};

alert("sayInfo" in person); // true
delete person.sayInfo;
alert("sayInfo" in person); // false
در مثال فوق پس از به کارگیری عملگر delete ، تابع sayInfo از شیء person حذف شده است. بنابراین در آخرین alert اعلام می‌کند که شیء person دیگر شامل این تابع نمی‌باشد.


ویژگی constructor

پس از عملگرهای فوق، یکی از پرکاربردترین ویژگی‌هایی که برای اشیاء وجود دارد، ویژگی constructor می‌باشد. در واقع این ویژگی نیز یکی از راهکارهای بررسی صحت و اعتبار متغیرها، آرگومانها و اشیا می‌باشد. ویژگی constructor ، به تابع سازنده‌ی یک شیء اشاره می‌کند و آن سازنده را به عنوان خروجی بر میگرداند. دقت داشته باشید که خروجی این ویژگی، خود تابع سازنده می‌باشد و یک مقدار رشته‌ای نیست. به مثال زیر توجه کنید:

var obj = {};
var a = new Array();
var x = 10;

alert(obj.constructor);
alert(obj.constructor === Object);
alert(typeof obj.constructor);
alert(a.constructor);
alert(x.constructor);

خروجی :

    function Object() { [native code] }
    true
    function
    function Array() { [native code] }
    function Number() { [native code] }
همانطور که در مثال فوق مشاهده می‌نمایید، کدهای obj.constructor ، a.constructor و x.constructor تابع سازنده‌ی این اشیا را برگردانده است. در مقایسه obj.constructor===Object نیز مشاهده می‌کنید که خروجی این ویژگی یک شیء می‌باشد و در typeof obj.constructor هم نشان دادیم که نوع این ویژگی یک تابع است.

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