نظرات مطالب
نظرات مطالب
خلاصه اشتراکهای روز دو شنبه 18 مهر 1390
با تشکر از پاشخ مفیدتون. اینکه ما اسم یک متد را صراحتا ر jQuery Ajax ذکر کنیم از لحاظ امنیتی مشکل زا خواهد بود؟
با تشکر
با تشکر
نظرات مطالب
نگاشت JSON به کلاسهای معادل آن
آقای نصیری من فقط وقتی که می خواهم با jQuery یک AJAX Post بزنم از JSON استفاده می کنم که آن هم خیلی عملا در گیرش نیستم (از JSON.Stringfy که معرفی کردید استفاده می کنم.)
JSON چه کاربردها و استفاده هایی دارد ؟
JSON چه کاربردها و استفاده هایی دارد ؟
نظرات مطالب
NiftyDotNet!
سلام!
شبیه روش jQuery هست چون از همون روش استفاده میکنه.خود کتاب خونه منظورم نیست.روش گرد کردن منظورمه.
موفق باشید.
یادآوری خوبی بود...
شبیه روش jQuery هست چون از همون روش استفاده میکنه.خود کتاب خونه منظورم نیست.روش گرد کردن منظورمه.
موفق باشید.
یادآوری خوبی بود...
نظرات مطالب
آشنایی با ویژگی DebuggerDisplay در VS.Net
با سلام و تشکر از شما که با این وبلاگ فوق العاده کمک زیادی حداقل به من در خصوص یادگیری JQUERY کردید در مورد attribute ها یک راهنمایی کنید که داریم برنامه می نویسیم کجا باید از attribute ها استفاده کرد و مجبوریم فقط از آن استفاده کنیم
پاسخ به بازخوردهای پروژهها
عدم امکان آپلود تصویر
دلیلش این هست که تمامی فرمها در این سیستم به صورت ajax به سمت سرور ارسال میشوند.
برای اپلود فایل به کمک ajax باید از از افزونهی jquery form plugin بهره بگیرید.
راه حلهای زیادی برای محاسبه و نمایش تعداد کاربران آنلاین یک برنامه وب وجود دارند و عموما مبتنی بر کار با متغیرهای سشن یا Application و امثال آن هستند. این روشها عموما دقیق نبوده و خصوصا قسمت قطع اتصال کاربر را نمیتوانند دقیقا تشخیص دهند. به همین جهت نیاز به یک تایمر دارند که مثلا اگر در 5 دقیقه قبل، کاربری درخواست مشاهده آدرسی را به سرور ارسال نکرده بود، از لیست کاربران آنلاین حذف شود.
در ادامه بجای این روشها، از SignalR برای محاسبه تعداد کاربران آنلاین و همچنین به روز رسانی بلادرنگ این عدد در سمت کاربر، استفاده خواهیم کرد.
تشخیص اتصال و قطع اتصال کاربران در SignalR
زیر ساختهای کلاس Hub موجود در SignalR، دارای متدهای ردیابی اتصال (OnConnected)، قطع اتصال (OnDisconnected) و یا برقراری مجدد اتصال کاربران (OnReconnected) هستند. با بازنویسی این متدها میتوان به تخمین بسیار دقیقی از تعداد کاربران آنلاین یک سایت رسید.
پیشنیازهای بحث
پیشنیازهای این بحث با مطلب «مثال - نمایش درصد پیشرفت عملیات توسط SignalR» یکی است. برای مثال نحوه دریافت وابستگیها، تنظیمات فایل global.asax و افزودن اسکریپتها، تفاوتی با مثال یاد شده ندارند.
تعریف هاب کاربران آنلاین برنامه
کدهای کامل هاب شمارش کاربران آنلاین را در اینجا ملاحظه میکنید؛ به همراه نکتهی نحوهی دریافت IP کاربر متصل شده به سایت، در یک هاب. کار افزودن یا حذف این کاربران به ConcurrentDictionary تعریف شده، در روالهای بازنویسی شده اتصال، قطع اتصال و اتصال مجدد یک کاربر، انجام شده است.
در اینجا، هم به IP کاربر و هم به ConnectionId او نیاز است. از این جهت که هر ConnectionId، معرف یک برگه جدید باز شده در مرورگر کاربر است. اگر صرفا IPها را پردازش کنیم، با بسته شدن یکی از چندین برگه مرورگر او که اکنون به سایت متصل هستند، آمار او را از دست خواهیم داد. این کاربر هنوز چندین برگه باز دیگر را دارد که با سایت در ارتباط هستند، اما چون IP او را از لیست حذف کردهایم (در نتیجه بسته شدن یکی از برگهها)، آمار کلی شخص را نیز از دست خواهیم داد. بنابراین هر دوی IP و ConnectionIdها باید پردازش شوند.
اگر برنامه شما دارای اعتبارسنجی است (یک صفحه لاگین دارد)، بهتر است بجای IP از this.Context.User.Identity.Name استفاده کنید.
کدهای سمت کلاینت نمایش آمار کاربران
با توجه به اینکه در هاب تعریف شده، متد پویای updateUsersOnlineCount، آمار تعداد کاربران متصل را (تعداد آی پیهای منحصربفرد متصل را) به کلاینتها ارسال میکند، بنابراین در سمت کلاینت نیز با تعریف callback ایی به همین نام، میتوان این آمار دریافتی را به کاربران سایت نمایش داد. آماری که به صورت خودکار با کم و زیاد شدن کاربران به روز شده و نیازی نیست کاربر به صورت دستی، صفحه را به روز کند.
کدهای کامل این مثال را از اینجا نیز میتوانید دریافت کنید:
SignalR05.zip
در ادامه بجای این روشها، از SignalR برای محاسبه تعداد کاربران آنلاین و همچنین به روز رسانی بلادرنگ این عدد در سمت کاربر، استفاده خواهیم کرد.
تشخیص اتصال و قطع اتصال کاربران در SignalR
زیر ساختهای کلاس Hub موجود در SignalR، دارای متدهای ردیابی اتصال (OnConnected)، قطع اتصال (OnDisconnected) و یا برقراری مجدد اتصال کاربران (OnReconnected) هستند. با بازنویسی این متدها میتوان به تخمین بسیار دقیقی از تعداد کاربران آنلاین یک سایت رسید.
پیشنیازهای بحث
پیشنیازهای این بحث با مطلب «مثال - نمایش درصد پیشرفت عملیات توسط SignalR» یکی است. برای مثال نحوه دریافت وابستگیها، تنظیمات فایل global.asax و افزودن اسکریپتها، تفاوتی با مثال یاد شده ندارند.
تعریف هاب کاربران آنلاین برنامه
using System.Collections.Concurrent; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; using Microsoft.AspNet.SignalR; namespace SignalR05.Common { public class OnlineUsersHub : Hub { public static readonly ConcurrentDictionary<string, string> OnlineUsers = new ConcurrentDictionary<string, string>(); public void UpdateUsersOnlineCount() { // آی پی معرف یک کاربر است // اما کانکشن آی دی معرف یک برگه جدید در مرورگر او است // هر کاربر میتواند چندین برگه را به یک سایت گشوده یا ببندد var ipsCount = OnlineUsers.Select(x => x.Value).Distinct().Count(); this.Clients.All.updateUsersOnlineCount(ipsCount); } /// <summary> /// اگر کاربران اعتبار سنجی شدهاند بهتر است از /// this.Context.User.Identity.Name /// بجای آی پی استفاده شود /// </summary> protected string GetUserIpAddress() { object environment; if (!Context.Request.Items.TryGetValue("owin.environment", out environment)) return null; object serverRemoteIpAddress; if (!((IDictionary<string, object>)environment).TryGetValue("server.RemoteIpAddress", out serverRemoteIpAddress)) return null; return serverRemoteIpAddress.ToString(); } public override Task OnConnected() { var ip = GetUserIpAddress(); OnlineUsers.TryAdd(this.Context.ConnectionId, ip); UpdateUsersOnlineCount(); return base.OnConnected(); } public override Task OnReconnected() { var ip = GetUserIpAddress(); OnlineUsers.TryAdd(this.Context.ConnectionId, ip); UpdateUsersOnlineCount(); return base.OnReconnected(); } public override Task OnDisconnected() { // در این حالت ممکن است مرورگر کاملا بسته شده باشد // یا حتی صرفا یک برگه مرورگر از چندین برگه متصل به سایت بسته شده باشند string ip; OnlineUsers.TryRemove(this.Context.ConnectionId, out ip); UpdateUsersOnlineCount(); return base.OnDisconnected(); } } }
در اینجا، هم به IP کاربر و هم به ConnectionId او نیاز است. از این جهت که هر ConnectionId، معرف یک برگه جدید باز شده در مرورگر کاربر است. اگر صرفا IPها را پردازش کنیم، با بسته شدن یکی از چندین برگه مرورگر او که اکنون به سایت متصل هستند، آمار او را از دست خواهیم داد. این کاربر هنوز چندین برگه باز دیگر را دارد که با سایت در ارتباط هستند، اما چون IP او را از لیست حذف کردهایم (در نتیجه بسته شدن یکی از برگهها)، آمار کلی شخص را نیز از دست خواهیم داد. بنابراین هر دوی IP و ConnectionIdها باید پردازش شوند.
اگر برنامه شما دارای اعتبارسنجی است (یک صفحه لاگین دارد)، بهتر است بجای IP از this.Context.User.Identity.Name استفاده کنید.
کدهای سمت کلاینت نمایش آمار کاربران
<html xmlns="http://www.w3.org/1999/xhtml"> <head runat="server"> <title></title> <script src="Scripts/jquery-1.6.4.min.js" type="text/javascript"></script> <script src="Scripts/jquery.signalR-1.1.3.min.js" type="text/javascript"></script> <script type="text/javascript" src='<%= ResolveClientUrl("~/signalr/hubs") %>'></script> </head> <body> <form id="form1" runat="server"> online users count: <span id="usersCount"></span> </form> <script type="text/javascript"> $(function () { $.connection.hub.logging = true; var onlineUsersHub = $.connection.onlineUsersHub; onlineUsersHub.client.updateUsersOnlineCount = function (count) { $('#usersCount').text(count); }; $.connection.hub.start(); }); </script> </body> </html>
کدهای کامل این مثال را از اینجا نیز میتوانید دریافت کنید:
SignalR05.zip
مسیرراهها
WPF
- آغاز کار با WPF
- آشنایی با WPF قسمت اول : ساختار سلسله مراتبی
- آشنایی با WPF قسمت دوم: Layouts بخش اول
- آشنایی با WPF قسمت سوم: Layouts بخش دوم
- آشنایی با WPF قسمت چهارم: کنترل ها
- آشنایی با WPF قسمت پنجم : DataContext بخش اول
- آشنایی با WPF قسمت پنجم : DataContext بخش دوم
- آشنایی با WPF قسمت ششم : DataContext بخش سوم
- انقیاد دادهها در WPF بخش اول
- انقیاد دادهها در WPF بخش دوم
- آشنایی با الگوی M-V-VM- قسمت اول
- M-V-VM - قسمت دوم
- آشنایی با الگوی M-V-VM - قسمت سوم
- آشنایی با الگوی M-V-VM - قسمت چهارم
- آشنایی با الگوی M-V-VM - قسمت پنجم
- Expression Blend WPF Tutorial
- طول و عرض WPF
- آموزش رایگان XAML از مایکروسافت
- سری آموزشی PRISM
- ویدیوهای رایگان آموزشی WPF
- ارتقاء از WinForms به WPF
- خلاصهای کاربردی در مورد Observable collection
- دو تنظیم ضروری VS.NET جهت کار با WPF و Silverlight
- معرفی WPF Extended toolkit
- WPF و قالبهایی جهت کنترل DataGrid
- خلاصهای از مبحث نمایش اطلاعات hierarchical در WPF
- WPF4 و ویندوز 7 : به خاطر سپاری لیست آخرین فایلهای گشوده شده توسط برنامه
- نمایش یک فایل PDF در WinForms ، WPF و سیلورلایت
- چند نکته در مورد WPF MediaElement و ویندوز XP
- تعیین Fallback font برای قلمهای فارسی در WPF
- آموزش ایجاد برنامههای چند زبانه در WPF
- آشنایی و استفاده از WCF Data Services در Visualstudio 2012
- بارگذاری UserControl در WPF به کمک الگوی MVVM
- معماری لایه بندی نرم افزار #1
- معماری لایه بندی نرم افزار #2
- معماری لایه بندی نرم افزار #3
- معماری لایه بندی نرم افزار #4
- نحوه نمایش تمام آیکونهای تعریف شده در یک قلم در WPF
- نحوه استخراج آیکونهای یک قلم در WPF
- مقیدسازی (DataBinding) در WPF زمانی که دسترسی به DataContext وجود ندارد
- فراخوانی یک متداز یک کنترل WPF از XAML
- آشنایی با Catel MVVM Frameowork
- استفاده از ItemsControl جهت ساختن کنترلهای پویا در WPF
- ساخت فرمهای generic در WPF و Windows Application
- استفاده از #F در پروژههای WPF
- Markup Extensions در XAML
- Debug کردن Binding در XAML
- Bind کردن Enum به ItemsSource در XAML
- دسترسی به فیلدهای Static در XAML
- نگاهی به درون سیستم Binding در WPF و یافتن مواردی که هنوز در حافظهاند
- بهبود کارآیی کنترلهای لیستی WPF در حین بارگذاری تعداد زیادی از رکوردها
- چگونه تشخیص دهیم UI Virtualization در WPF خاموش شده است؟
- اضافه کردن امکان ویرایش WPF DataGrid در صورت نامعتبر بودن سلول ها
- انقیاد RadioButtonها در WPF به یک Enum
- یکی کردن اسمبلیهای یک پروژهی WPF
- بستن یک پنجره از طریق ViewModel با استفاده از خصوصیتهای پیوست شده هنگام استفاده از الگوی MVVM
- حرکت روی سلولهای دیتا گرید با فشردن کلید Enter در برنامههای WPF
- دسترسی به Collectionها در یک ترد دیگر در WPF
- آموزش WAF
- آموزش WAF (بررسی ساختار همراه با پیاده سازی یک مثال)
- آموزش WAF (بررسی Commandها)
- آموزش WAF (مشاهده تغییرات خواص ViewModel در Controller)
- تصادفی کردن آیتمهای لیست با استفاده از Extension Method
- استفاده از AvalonEdit در WPF
- فرمت شرطی اطلاعات به کمک تریگرها در WPF
- first chance exception چیست؟
- معرفی کتابخانهی OxyPlot
- معرفی DNTProfiler
- چگونه برنامههای دات نت را خارج از ویژوال استودیو دیباگ کنیم؟
- اسکرول روان لیستهای مجازی سازی شده در WPF 4.5
- پیاده سازی INotifyPropertyChanged با استفاده از Unity Container
State machine چیست؟
State machine مدلی است بیانگر نحوه واکنش سیستم به وقایع مختلف. یک ماشین حالت وضعیت جاری قسمتی از سیستم را نگهداری کرده و به ورودیهای مختلف پاسخ میدهد. این ورودیها در نهایت وضعیت سیستم را تغییر خواهند داد.
نحوه پاسخگویی یک ماشین حالت (State machine) را به رویدادی خاص، انتقال (Transition) مینامند. در یک انتقال مشخص میشود که ماشین حالت بر اساس وضعیت جاری خود، با دریافت یک رویداد، چه عکس العملی را باید بروز دهد. عموما (و نه همیشه) در حین پاسخگویی ماشین حالت به رویدادهای رسیده، وضعیت آن نیز تغییر خواهد کرد. در اینجا گاهی از اوقات پیش از انجام عملیاتی، نیاز است شرطی بررسی شده و سپس انتقالی رخ دهد. به این شرط، guard گفته میشود.
بنابراین به صورت خلاصه، یک ماشین حالت، مدلی است از رفتاری خاص، تشکیل شده از حالات، رویدادها، انتقالات، اعمال (actions) و شرطها (Guards). در اینجا:
- یک حالت (State)، شرطی منحصربفرد در طول عمر ماشین حالت است. در هر زمان مشخصی، ماشین حالت در یکی از حالات از پیش تعریف شده خود قرار خواهد داشت.
- یک رویداد (Event)، اتفاقی است که به ماشین حالت اعمال میشود؛ یا همان ورودیهای سیستم.
- یک انتقال (Transition)، بیانگر نحوه رفتار ماشین حالت جهت پاسخگویی به رویداد وارده بر اساس وضعیت جاری خود میباشد. در طی یک انتقال، سیستم از یک حالت به حالتی دیگر منتقل خواهد شد.
- برای انجام یک انتقال، نیاز است یک شرط (Guard/Conditional Logic) بررسی شده و در صورت true بودن آن، انتقال صورت گیرد.
- یک عمل (Action)، بیانگر نحوه پاسخگویی ماشین حالت در طول دوره انتقال است.
چگونه میتوان الگوی ماشین حالت را تشخیص داد؟
اکثر برنامههای وب، متشکل از پیاده سازی چندین ماشین حالت میباشند؛ مانند ثبت نام در سایت، درخواست یک کتاب از کتابخانه، ارسال درخواستها و پاسخگویی به آنها و یا حتی ارسال یک مطلب در سایت، تائید و انتشار آن.
البته عموما در حین طراحی برنامهها، کمتر به این نوع مسایل به شکل یک ماشین حالت نگاه میشود. به همین جهت بهتر است معیارهایی را برای شناخت زود هنگام آنها مدنظر داشته باشیم:
- آیا در جدول بانک اطلاعاتی خود فیلدهایی مانند State (حالت) یا Status (وضعیت)دارید؟ اگر بله، به این معنا است که در حال کار با یک ماشین حالت هستید.
- عموما فیلدهای Bit و Boolean، بیانگر حضور ماشینهای حالت هستند. مانند IsPublished ، IsPaid و یا حتی داشتن یک فیلد timeStamp که میتواند NULL بپذیرد نیز بیانگر استفاده از ماشین حالت است؛ مانند فیلدهای published_at، paid_at و یا confirmed_at.
- داشتن رکوردهایی که تنها در طول یک بازه زمانی خاص، معتبر هستند. برای مثال آبونه شدن در یک سایت در طول یک بازه زمانی مشخص.
- اعمال چند مرحلهای؛ مانند ثبت نام در سایت و دریافت ایمیل فعال سازی. سپس فعال سازی اکانت از طریق ایمیل.
مثالی ساده از یک ماشین حالت
یک کلید برق را در نظر بگیرید. این کلید دارای دو حالت (states) روشن و خاموش است. زمانی که خاموش است، با دریافت رخدادی (event)، به وضعیت (state/status) روشن، منتقل خواهد شد (Transition) و برعکس.
در اینجا حالات با مستطیلهای گوشه گرد نمایش داده شدهاند. انتقالات توسط فلشهایی انحناء دار که حالات را به یکدیگر متصل میکنند، مشخص گردیدهاند. برچسبهای هر فلش، مشخص کننده نام رویدادی است که سبب انتقال و تغییر حالت میگردد. با شروع یک ماشین حالت، این ماشین در یکی از وضعیتهای از پیش تعیین شدهاش قرار خواهد گرفت (initial state)؛ که در اینجا حالت خاموش است.
این نوع نمودارها میتوانند شامل جزئیات بیشتری نیز باشند؛ مانند برچسبهایی که نمایانگر اعمال قابل انجام در طی یک انتقال هستند.
رسم ماشینهای حالت در برنامههای وب، به کمک کتابخانه jsPlumb
کتابخانههای زیادی برای رسم فلوچارت، گردشهای کاری، ماشینهای حالت و امثال آن جهت برنامههای وب وجود دارند و یکی از معروفترینهای آنها کتابخانه jsPlumb است. این کتابخانه به صورت یک افزونه jQuery طراحی شده است؛ اما به عنوان افزونهای برای کتابخانههای MooTools و یا YUI3/Yahoo User Interface 3 نیز قابل استفاده میباشد. کتابخانه jsPlumb در مرورگرهای جدید از امکانات ترسیم SVG و یا HTML5 Canvas استفاده میکند. برای سازگاری با مرورگرهای قدیمیتر مانند IE8 به صورت خودکار به VML سوئیچ خواهد کرد. همچنین این کتابخانه امکانات ترسیم تعاملی قطعات به هم متصل شونده را نیز دارا است (شبیه به طراح یک گردش کاری). البته برای اضافه شدن امکاناتی مانند کشیدن و رها کردن در آن نیاز به jQuery-UI نیز خواهد داشت.
برای نمونه اگر بخواهیم مثال فوق را توسط jsPlumb ترسیم کنیم، روش کار به صورت زیر خواهد بود:
مستندات کامل jsPlumb را در سایت آن میتوان ملاحظه نمود.
در مثال فوق، ابتدا css و فایلهای js مورد نیاز ذکر شدهاند. توسط css، مکان قرارگیری اولیه المانهای متناظر با حالات، مشخص میشوند.
سپس زمانیکه اشیاء صفحه در دسترس هستند، تنظیمات jsPlumb انجام خواهد شد. برای مثال در اینجا نوع نمایشی Endpointها به نقطه تنظیم شده است. موارد دیگری مانند مستطیل نیز قابل تنظیم است. سپس نیاز است منبع و مقصدها به کتابخانه jsPlumb معرفی شوند. به کمک متد jsPlumb.makeTarget، تمام المانهای دارای کلاس w به عنوان منبع و با شمارش divهایی با class=ep، مقصدهای قابل اتصال تعیین شدهاند (jsPlumb.makeSource). متد jsPlumb.bind یک callback function است و هربار که اتصالی برقرار میشود، فراخوانی خواهد شد. متد jsPlumb.draggable تمام عناصر دارای کلاس w را قابل کشیدن و رها کردن میکند و در آخر توسط متدهای jsPlumb.connect، مقصد و منبعهای مشخصی را هم متصل خواهیم کرد. نمونه نهایی تهیه شده برای بررسی بیشتر.
برای مطالعه بیشتر
Finite-state machine
UML state machine
UML 2 State Machine Diagrams
مثالهایی در این مورد
State machine مدلی است بیانگر نحوه واکنش سیستم به وقایع مختلف. یک ماشین حالت وضعیت جاری قسمتی از سیستم را نگهداری کرده و به ورودیهای مختلف پاسخ میدهد. این ورودیها در نهایت وضعیت سیستم را تغییر خواهند داد.
نحوه پاسخگویی یک ماشین حالت (State machine) را به رویدادی خاص، انتقال (Transition) مینامند. در یک انتقال مشخص میشود که ماشین حالت بر اساس وضعیت جاری خود، با دریافت یک رویداد، چه عکس العملی را باید بروز دهد. عموما (و نه همیشه) در حین پاسخگویی ماشین حالت به رویدادهای رسیده، وضعیت آن نیز تغییر خواهد کرد. در اینجا گاهی از اوقات پیش از انجام عملیاتی، نیاز است شرطی بررسی شده و سپس انتقالی رخ دهد. به این شرط، guard گفته میشود.
بنابراین به صورت خلاصه، یک ماشین حالت، مدلی است از رفتاری خاص، تشکیل شده از حالات، رویدادها، انتقالات، اعمال (actions) و شرطها (Guards). در اینجا:
- یک حالت (State)، شرطی منحصربفرد در طول عمر ماشین حالت است. در هر زمان مشخصی، ماشین حالت در یکی از حالات از پیش تعریف شده خود قرار خواهد داشت.
- یک رویداد (Event)، اتفاقی است که به ماشین حالت اعمال میشود؛ یا همان ورودیهای سیستم.
- یک انتقال (Transition)، بیانگر نحوه رفتار ماشین حالت جهت پاسخگویی به رویداد وارده بر اساس وضعیت جاری خود میباشد. در طی یک انتقال، سیستم از یک حالت به حالتی دیگر منتقل خواهد شد.
- برای انجام یک انتقال، نیاز است یک شرط (Guard/Conditional Logic) بررسی شده و در صورت true بودن آن، انتقال صورت گیرد.
- یک عمل (Action)، بیانگر نحوه پاسخگویی ماشین حالت در طول دوره انتقال است.
چگونه میتوان الگوی ماشین حالت را تشخیص داد؟
اکثر برنامههای وب، متشکل از پیاده سازی چندین ماشین حالت میباشند؛ مانند ثبت نام در سایت، درخواست یک کتاب از کتابخانه، ارسال درخواستها و پاسخگویی به آنها و یا حتی ارسال یک مطلب در سایت، تائید و انتشار آن.
البته عموما در حین طراحی برنامهها، کمتر به این نوع مسایل به شکل یک ماشین حالت نگاه میشود. به همین جهت بهتر است معیارهایی را برای شناخت زود هنگام آنها مدنظر داشته باشیم:
- آیا در جدول بانک اطلاعاتی خود فیلدهایی مانند State (حالت) یا Status (وضعیت)دارید؟ اگر بله، به این معنا است که در حال کار با یک ماشین حالت هستید.
- عموما فیلدهای Bit و Boolean، بیانگر حضور ماشینهای حالت هستند. مانند IsPublished ، IsPaid و یا حتی داشتن یک فیلد timeStamp که میتواند NULL بپذیرد نیز بیانگر استفاده از ماشین حالت است؛ مانند فیلدهای published_at، paid_at و یا confirmed_at.
- داشتن رکوردهایی که تنها در طول یک بازه زمانی خاص، معتبر هستند. برای مثال آبونه شدن در یک سایت در طول یک بازه زمانی مشخص.
- اعمال چند مرحلهای؛ مانند ثبت نام در سایت و دریافت ایمیل فعال سازی. سپس فعال سازی اکانت از طریق ایمیل.
مثالی ساده از یک ماشین حالت
یک کلید برق را در نظر بگیرید. این کلید دارای دو حالت (states) روشن و خاموش است. زمانی که خاموش است، با دریافت رخدادی (event)، به وضعیت (state/status) روشن، منتقل خواهد شد (Transition) و برعکس.
در اینجا حالات با مستطیلهای گوشه گرد نمایش داده شدهاند. انتقالات توسط فلشهایی انحناء دار که حالات را به یکدیگر متصل میکنند، مشخص گردیدهاند. برچسبهای هر فلش، مشخص کننده نام رویدادی است که سبب انتقال و تغییر حالت میگردد. با شروع یک ماشین حالت، این ماشین در یکی از وضعیتهای از پیش تعیین شدهاش قرار خواهد گرفت (initial state)؛ که در اینجا حالت خاموش است.
این نوع نمودارها میتوانند شامل جزئیات بیشتری نیز باشند؛ مانند برچسبهایی که نمایانگر اعمال قابل انجام در طی یک انتقال هستند.
رسم ماشینهای حالت در برنامههای وب، به کمک کتابخانه jsPlumb
کتابخانههای زیادی برای رسم فلوچارت، گردشهای کاری، ماشینهای حالت و امثال آن جهت برنامههای وب وجود دارند و یکی از معروفترینهای آنها کتابخانه jsPlumb است. این کتابخانه به صورت یک افزونه jQuery طراحی شده است؛ اما به عنوان افزونهای برای کتابخانههای MooTools و یا YUI3/Yahoo User Interface 3 نیز قابل استفاده میباشد. کتابخانه jsPlumb در مرورگرهای جدید از امکانات ترسیم SVG و یا HTML5 Canvas استفاده میکند. برای سازگاری با مرورگرهای قدیمیتر مانند IE8 به صورت خودکار به VML سوئیچ خواهد کرد. همچنین این کتابخانه امکانات ترسیم تعاملی قطعات به هم متصل شونده را نیز دارا است (شبیه به طراح یک گردش کاری). البته برای اضافه شدن امکاناتی مانند کشیدن و رها کردن در آن نیاز به jQuery-UI نیز خواهد داشت.
برای نمونه اگر بخواهیم مثال فوق را توسط jsPlumb ترسیم کنیم، روش کار به صورت زیر خواهد بود:
<!doctype html> <html> <head> <title>State Machine Demonstration</title> <style type="text/css"> #opened { left: 10em; top: 5em; } #off { left: 12em; top: 15em; } #on { left: 28em; top: 15em; } .w { width: 5em; padding: 1em; position: absolute; border: 1px solid black; z-index: 4; border-radius: 1em; border: 1px solid #346789; box-shadow: 2px 2px 19px #e0e0e0; -o-box-shadow: 2px 2px 19px #e0e0e0; -webkit-box-shadow: 2px 2px 19px #e0e0e0; -moz-box-shadow: 2px 2px 19px #e0e0e0; -moz-border-radius: 0.5em; border-radius: 0.5em; opacity: 0.8; filter: alpha(opacity=80); cursor: move; } .ep { float: right; width: 1em; height: 1em; background-color: #994466; cursor: pointer; } .labelClass { font-size: 20pt; } </style> <script type="text/javascript" src="jquery.min.js"></script> <script type="text/javascript" src="jquery-ui.min.js"></script> <script type="text/javascript" src="jquery.jsPlumb-all-min.js"></script> <script type="text/javascript"> $(document).ready(function () { jsPlumb.importDefaults({ Endpoint: ["Dot", { radius: 5}], HoverPaintStyle: { strokeStyle: "blue", lineWidth: 2 }, ConnectionOverlays: [ ["Arrow", { location: 1, id: "arrow", length: 14, foldback: 0.8}] ] }); jsPlumb.makeTarget($(".w"), { dropOptions: { hoverClass: "dragHover" }, anchor: "Continuous" }); $(".ep").each(function (i, e) { var p = $(e).parent(); jsPlumb.makeSource($(e), { parent: p, anchor: "Continuous", connector: ["StateMachine", { curviness: 20}], connectorStyle: { strokeStyle: '#42a62c', lineWidth: 2 }, maxConnections: 2, onMaxConnections: function (info, e) { alert("Maximum connections (" + info.maxConnections + ") reached"); } }); }); jsPlumb.bind("connection", function (info) { }); jsPlumb.draggable($(".w")); jsPlumb.connect({ source: "opened", target: "off" }); jsPlumb.connect({ source: "off", target: "on", label: "Turn On" }); jsPlumb.connect({ source: "on", target: "off", label: "Turn Off" }); }); </script> </head> <body> <div class="w" id="opened"> Begin <div class="ep"> </div> </div> <div class="w" id="off"> Off <div class="ep"> </div> </div> <div class="w" id="on"> On <div class="ep"> </div> </div> </body> </html>
در مثال فوق، ابتدا css و فایلهای js مورد نیاز ذکر شدهاند. توسط css، مکان قرارگیری اولیه المانهای متناظر با حالات، مشخص میشوند.
سپس زمانیکه اشیاء صفحه در دسترس هستند، تنظیمات jsPlumb انجام خواهد شد. برای مثال در اینجا نوع نمایشی Endpointها به نقطه تنظیم شده است. موارد دیگری مانند مستطیل نیز قابل تنظیم است. سپس نیاز است منبع و مقصدها به کتابخانه jsPlumb معرفی شوند. به کمک متد jsPlumb.makeTarget، تمام المانهای دارای کلاس w به عنوان منبع و با شمارش divهایی با class=ep، مقصدهای قابل اتصال تعیین شدهاند (jsPlumb.makeSource). متد jsPlumb.bind یک callback function است و هربار که اتصالی برقرار میشود، فراخوانی خواهد شد. متد jsPlumb.draggable تمام عناصر دارای کلاس w را قابل کشیدن و رها کردن میکند و در آخر توسط متدهای jsPlumb.connect، مقصد و منبعهای مشخصی را هم متصل خواهیم کرد. نمونه نهایی تهیه شده برای بررسی بیشتر.
برای مطالعه بیشتر
Finite-state machine
UML state machine
UML 2 State Machine Diagrams
مثالهایی در این مورد
PersianDatePicker یک DatePicker شمسی برای نمایش تاریخ شمسی در صفحات وب است.
مهمترین ویژگیها :
textBox : کنترلی است که DatePicker برای آن نمایش داده میشود.
today : تاریخ روز جاری است.
برای مثال :
در ASP.NET Web Forms :
در مثال بالا برای گرفتن تاریخ روز جاری از PersianDateTime استفاده شده است.
در ASP.NET MVC یا PHP یا هر زبان دیگری کافیست onclick کنترل متنی مورد نظر در سمت سرور مانند مثال بالا مقدار داده شود. یا میتوان image کوچکی کنار textbox مورد نظر قرار داد و onclick آن تنظیم شود.
برای استفاده از PersianDatePicker میتوانید آنرا از NuGet دریافت کنید :
- از تاریخ سرور برای نمایش روز جاری استفاده میکند.
- به زبان جاوااسکریپت است و نیازی به سایر فریمورکها مانند jQuery ندارد.
- سبک و کم حجم است (3.5 کیلوبایت)
- روزها به صورت عمودی لیست شدهاند مانند برنامه هفتگی مدرسه که کاربران فارسیزبان با آن راحتترند.
طرز استفاده :
PersianDatePicker.Show(textBox, today)
today : تاریخ روز جاری است.
برای مثال :
<html> <head> <script type="text/javascript" src="Scripts/PersianDatePicker.min.js"></script> <link type="text/css" rel="stylesheet" href="Content/PersianDatePicker.min.css" /> </head> <body> <input type="text" onclick="PersianDatePicker.Show(this, '1392/03/22');" /> </body> </html>
<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="WebForm1.aspx.cs" Inherits="WebApplication4.WebForm1" %> <!DOCTYPE html> <html xmlns="http://www.w3.org/1999/xhtml"> <head runat="server"> <title></title> <script src="Scripts/PersianDatePicker.min.js"></script> <link href="Content/PersianDatePicker.min.css" rel="stylesheet" /> </head> <body> <form id="form1" runat="server"> <div> <asp:Label runat="server" Text="Label" AssociatedControlID="TextBox1">تاریخ : </asp:Label> <asp:TextBox runat="server" ID="TextBox1"></asp:TextBox> </div> </form> </body> </html>
public partial class WebForm1 : System.Web.UI.Page { protected void Page_Load(object sender, EventArgs e) { var now = PersianDateTime.Now; var today = now.ToString(PersianDateTimeFormat.Date); TextBox1.Attributes["onclick"] = "PersianDatePicker.Show(this,'" + today + "');"; } }
در مثال بالا برای گرفتن تاریخ روز جاری از PersianDateTime استفاده شده است.
در ASP.NET MVC یا PHP یا هر زبان دیگری کافیست onclick کنترل متنی مورد نظر در سمت سرور مانند مثال بالا مقدار داده شود. یا میتوان image کوچکی کنار textbox مورد نظر قرار داد و onclick آن تنظیم شود.
برای استفاده از PersianDatePicker میتوانید آنرا از NuGet دریافت کنید :
PM> Install-Package PersianDatePicker