تاریخ شمسی برای blogger !
- میلادی را هم به روش فارسی اضافه کردم :)
- ضمنا اسکریپت گریس مانکی هم به روز شد تا با آن تداخل نکند.
به لطف استاندارد مدرن و هنوز فراگیر نشدهی WebAssembly ، امروزه همهی مرورگرهای مدرن میتوانند بجای اجرای جاوا اسکریپت، یک زبان bytecode استانداردِ سطح پایین و شبیه به زبان اسمبلی را اجرا کنند. استفاده از WebAssembly میتواند موجب اجرای سریعتر کد و کاهش حجم آن شود. اما مهمترین مزیت این هست که امروز میتوانیم همهی زبانهای قدرتمند، نظیر سی شارپ را به نحوی کامپایل کنیم که خروجیِ نهایی، منطبق با استاندارد webassembly باشد و به صورت native در مرورگرها، دات نت را اجرا کنیم.
کامپایل سی شارپ به WebAssembly توسط تیم Mono مایکروسافت انجام شده و عمده مشکلات فنی سر راه برداشته شدهاند. اما برای اینکه عملا بشود از دات نت در مرورگرها استفاده کرد، مایکروسافت در پی پیاده سازی پروژهی جاه طلبانهای به نام Blazor میباشد. در واقع Blazor فریم ورک Client-Side مبتنی بر دات نت خواهد بود؛ الهام گرفته از فریم ورکهای کنونی (مانند Angular و React) و رقیبی جدید برای آنها. فریم ورک Blazor هم مانند آنها حول مفهوم Component شکل گرفتهاست. کامپوننتهایی که کلاسهای سی شارپی هستند و با زبان Razor توسعه داده شدهاند.
استفاده از دات نت در مرورگرها میتواند موجب این شود که کد بیشتری را بین سرور و کلاینت بتوانیم به اشتراک بگذاریم و نیاز به دوباره کاری در هر دو سمت را نداشته باشیم. علاوه بر این توسعه دهندگان سی شارپ کمی بیشتر به مفهوم Full Stack Developer نزدیک خواهند شد.
همچنین با استفاده از WebAssembly میتوانیم به تمام کتابخانههای موجود جاوااسکریپتی هم دسترسی داشته باشیم و محدودیتی در این زمینه وجود ندارد. همچنین میتوان DOM را هم از این طریق مدیریت و دستکاری کرد.
در حال حاضر تیم AspNet عهده دار کار بر روی پروژهی Blazor شدهاست. از نوشتههای آنها چنین بر میآید که تا نهایی شدن این پروژه هنوز باید صبر کنیم.
روش به کارگیری تقویم در Blazor
<link href="css/js-persian-cal.css" rel="stylesheet"/>
<script src="js/js-persian-cal.min.js"></script>
<input type="text" id="pcal1" />
protected override async Task OnAfterRenderAsync(bool firstRender) { int dateFieldCount = 1; if (firstRender) { for (int i = 1; i <= dateFieldCount; i++) { await JsRuntime.InvokeVoidAsync("CallAmib", "pcal" + i.ToString()); } } }
@inject IJSRuntime JsRuntime
window.CallAmib = (objCal1) => { new AMIB.persianCalendar(objCal1); }
@using Microsoft.AspNetCore.Components.Web @namespace ShamsiDatePickerBlazor.Pages @addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers <!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <base href="~/" /> <link rel="stylesheet" href="css/bootstrap/bootstrap.min.css" /> <link href="css/site.css" rel="stylesheet" /> <link href="css/js-persian-cal.css" rel="stylesheet" /> <component type="typeof(HeadOutlet)" render-mode="ServerPrerendered" /> </head> <body> @RenderBody() <div id="blazor-error-ui"> <environment include="Staging,Production"> An error has occurred. This application may no longer respond until reloaded. </environment> <environment include="Development"> An unhandled exception has occurred. See browser dev tools for details. </environment> <a href="">Reload</a> <a>🗙</a> </div> <script src="js/js-persian-cal.min.js"></script> <script src="js/CallAmib.js"></script> <script src="_framework/blazor.server.js"></script> </body> </html>
مشکل!!
window.CallCall = (objCal1) => { new AMIB.persianCalendar(objCal1,{ onchange: function(pdate) { DotNet.invokeMethodAsync('ShamsiDatePickerBlazor', 'DateChanged', pdate.toString()).then( (date) => { console.log(data); } ); } }); }
static string selectedDate; [JSInvokable] public static void DateChanged(string pdate) { selectedDate = pdate; }
وضعیت توسعهی برنامههای وب، پیش از ارائهی Blazor
عموما برای توسعهی برنامههای وب، در سمت سرور آنها از زبانهایی مانند C#، Java و Python و امثال آنها استفاده میشود؛ اما این وضعیت در سمت کلاینت فرق میکند. در سمت کلاینت، عموما از فریمورکها و کتابخانههای جاوا اسکریپتی مانند Angular ،React ،Vue.js ،jQuery و غیره استفاده میشود.
همانطور که مشاهده میکنید، فراگیری و اجرای این دو گروه متفاوت از زبانها، مشکل و وقتگیر است. بنابراین چقدر خوب میشد اگر امکان تهیهی هر دو قسمت برنامههای وب، تنها با یک زبان میسر میشد. با استفاده از Blazor، این آرزو میسر شدهاست.
با استفاده از Blazor میتوان کدهای تعاملی UI را بجای استفاده از زبان جاوا اسکریپت، با کمک زبان #C تهیه کرد. به این ترتیب با استفاده از یک زبان میتوان کدهای سمت سرور و سمت کلاینت را پیاده سازی کرد. البته شاید این سؤال مطرح شود که مرورگرها تنها قادر به درک کدهای HTML و جاوا اسکریپت هستند و نه #C، بنابراین چگونه میتوان از زبان #C در مرورگرها نیز استفاده کرد؟ پاسخ به آن، به فناوری جدید «وب اسمبلی» بر میگردد. Blazor با استفاده از «وب اسمبلی» است که میتواند کدهای #C را درون مرورگر اجرا کند.
حالتهای مختلف هاست و ارائهی برنامههای مبتنی بر Blazor
برنامههای مبتنی بر Blazor، به دو روش مختلف قابل ارائه هستند:
الف) Blazor Server
Blazor Server، در اساس یک برنامهی استاندارد ASP.NET Core است که در آن تمام قابلیتهای سمت سرور، مانند کار با EF-Core، میسر است و امکان دسترسی به این امکانات به صورت یکپارچهای در سراسر برنامه وجود دارد. در این حالت، کامپوننتهای Blazor، بجای اجرای بر روی مرورگر کاربر، در سمت سرور اجرا میشوند. این تعاملات و به روز رسانیهای UI، توسط یک اتصال دائم SignalR مدیریت میشوند.
همانطور که مشاهده میکنید، در حالت هاست سمت سرور، همه چیز، منجمله کامپوننتهای Blazor، در همان سمت سرور قرار دارند و این اتصال پشت صحنهی SignalR است که کار تبادل اطلاعات ارسالی و رندر شده را بر عهده میگیرد.
ب) Blazor web assembly
در این حالت با استفاده از فناوری جدید «وب اسمبلی»، تمام کدهای یک برنامهی مبتنی بر Blazor به کمک NET Runtime.، داخل مرورگر اجرا میشود. به Blazor web assembly باید همانند فریمورکهای SPA (تک صفحهای وب)، مانند Angular و React نگاه کرد؛ با یک تفاوت مهم: در اینجا بجای استفاده از جاو اسکریپت برای نوشتن برنامهی SPA، از #C استفاده میشود. اگر به تصویر فوق دقت کنید، در حالت اجرای برنامههای Blazor web assembly، تنها به مرورگر کاربر نیاز است و همه چیز داخل آن قرار میگیرد. در اینجا دیگر خبری از یک اتصال دائم SignalR با سرور وجود ندارد.
البته باید دقت داشت که از فناوری وب اسمبلی، در تمام مرورگرهای جدید پشتیبانی میشود؛ منهای IE 11. در این حالت مرورگر کل برنامهی Blazor را دریافت میکند (همانند دریافت کل کدهای یک برنامهی Angular و یا React) و بدون استفاده از رندر سمت سرور حالت الف، قابلیت تعامل با کاربر را دارد.
بدیهی است با توجه به اینکه Blazor web assembly مستقیما داخل مرورگر اجرا میشود، دیگر همانند حالت الف، امکان دسترسی مستقیم به فناوریها و امکانات سمت سرور، مانند کار مستقیم با EF-Core را نخواهد داشت. برای این منظور دقیقا همانند روش کار با سایر فریم ورکهای SPA، نیاز به تهیهی یک ASP.NET Core Web API جهت تعامل با سرور خواهد بود.
مزایا و معایب حالتهای مختلف هاست برنامههای Blazor
الف) Blazor Server
مزایا:
- حجم دریافتی توسط مرورگر در این حالت بسیار کم است.
- امکان دسترسی به تمام امکانات سمت سرور را دارد؛ مانند تمام کتابخانههای سمت سرور و همچنین امکان دیباگ آن نیز همانند سایر برنامههای سمت سرور است.
- بر روی مرورگرهای قدیمی نیز قابل اجرا است؛ چون بدون نیاز به فناوری جدید «وب اسمبلی» کار میکند.
معایب:
- رندر شدن UI آن نسبت به حالت ب، کندتر است. از این جهت که تمام تعاملات UI آن، توسط اتصال SignalR به سمت سرور ارسال شده و سپس نتیجهی نهایی رندر شده، به سمت کلاینت بازگشت داده میشود.
- پشتیبانی از اجرای offline آن وجود ندارد. اگر اتصال SignalR موجود قطع شود، دیگر نمیتوان از برنامه استفاده کرد.
- با توجه به نیاز به استفادهی از یک اتصال دائم SignalR به ازای هر کاربر، مقیاس پذیری این نوع برنامهها کمتر است. البته اگر تعداد کاربران برنامههای شما در یک شبکهی اینترانت داخلی شرکتی محدود است، این مورد مشکل خاصی نخواهد بود. از دیدگاهی دیگر اگر تعداد کاربران برنامهی شما بسیار زیاد است، استفاده از Blazor Server توصیه نمیشود. البته باید دقت داشت که سروری با 4GB RAM، میتواند 5000 کاربر همزمان SignalR را مدیریت کند.
ب) Blazor web assembly یا به اختصار Blazor WASM
مزایا:
- هیچ نوع وابستگی به سمت سرور ندارد. همینقدر که برنامه توسط مرورگر دریافت شد، قابل اجر است.
- برای هاست آن الزاما نیازی به یک سرور IIS و یا یک وب سرور ASP.NET Core نیست.
- امکان ارائهی آن توسط یک CDN نیز وجود دارد.
- چون در این حالت کل برنامه توسط مرورگر دریافت میشود، قابلیت اجرای آفلاین را نیز پیدا میکند.
- برای کار، نیازی به اتصال دائم SignalR را ندارد؛ به همین جهت مقیاس پذیری آن بیشتر است.
معایب:
- حتما نیاز به استفادهی از مرورگرهای جدید با پشتیبانی از web assembly را دارد؛ برای مثال نیاز به کروم نگارش 57 به بعد و فایرفاکس نگارش 52 به بعد را دارد و بر روی IE اجرا نمیشود.
- چون کل برنامه در این حالت توسط مرورگر دریافت میشود، حجم ابتدایی دریافت آن کمی بالا است.
- میدان دید و عملکرد آن همانند سایر برنامههای SPA، محدود است به امکاناتی که مرورگر، در اختیار برنامه قرار میدهد.
ایجاد پروژههای خالی Blazor Server و Blazor web assembly
یا میتوانید از ویژوال استودیوی کامل و منوی افزودن پروژهی آن برای اینکار استفاده کنید و یا اگر به خروجی دستور dotnet new --list مراجعه کنیم، SDK دات نت 5، به همراه دو قالب مرتبط زیر نیز هست:
C:\Users\Vahid>dotnet new --list Templates Short Name Language Tags -------------------------------------------- ------------------- ------------ ---------------------- Blazor Server App blazorserver [C#] Web/Blazor Blazor WebAssembly App blazorwasm [C#] Web/Blazor/WebAssembly
در قسمت بعد، این دو پروژهی خالی فوق را ایجاد کرده و ساختار آنها را بررسی میکنیم. همچنین نکاتی را هم که در این قسمت در مورد نحوهی هاست این برنامهها عنوان شد، بر روی این پروژهها مشاهده خواهیم کرد.
[HttpPost,AjaxOnly, ValidateAntiForgeryToken] public virtual JsonResult Create(AddDeviceGroupViewModel deviceGroupViewModel) { if (ModelState.IsNotValid()) { Response.StatusCode = (int)HttpStatusCode.BadRequest; return Json(new { success = false, message = ModelState.FirstErrorMessage(), notificationType = NotificationType.Error }, JsonRequestBehavior.AllowGet); } var result = _deviceGroupService.Add(deviceGroupViewModel); // other codes }
@using (Ajax.BeginForm(MVC.Admin.DeviceGroup.Create(), new AjaxOptions { HttpMethod = "POST", OnSuccess = "saveAjaxForm", OnFailure = "SaveFailure" })) { // form content }
function SaveFailure(data) { $("button[type=submit]").prop('disabled', false); var result = $.parseJSON(data.responseText); showMessage(result.message, result.notificationType); }
مشکل به وجود آمده حاصل اضافه شدن تگهای زیر به وب کانفیگ بود :
<httpErrors errorMode="Custom"> <remove statusCode="404"/> <error statusCode="404" path="/Error/NotFound" responseMode="ExecuteURL"/> </httpErrors>
Response.StatusCode = (int)HttpStatusCode.BadRequest;
و در خروجی تنها مقداری که به سمت کاربر برگشت داده میشد، مقدار BadRequest بود و خط زیر باعث خطا و توقف برنامه میشد:
var result = $.parseJSON(data.responseText);
همچنین در صورتیکه قصد داشتید تگهای فوق را در web.config داشته باشید (جهت هندل کردن صفحات پیدا نشده) میتوانید از مقدار دهی TrySkipIISCustomError با true این مشکل را رفع کنید.
Response.TrySkipIisCustomErrors = true;
روشی دیگر:
<system.webServer> <httpErrors errorMode="DetailedLocalOnly" existingResponse="PassThrough" />
CoffeeScript #1
مقدمه
CoffeeScript یک زبان برنامه نویسی برای تولید کدهای جاوااسکریپت است که Syntax آن الهام گرفته از Ruby و Python است و بسیاری از ویژگیهایش، از این دو زبان پیاده سازی شده است.سوالی که ممکن است برای هر کسی پیش بیاید این است که چرا باید از CoffeeScript استفاده کرد و یا چرا نوشتن CoffeeScript بهتر از نوشتن مستقیم جاوااسکریپت است؟
از جمله دلایلی که میشود عنوان کرد:
حجم کد کمتری نوشته میشود (تجربه شخصی من: تقریبا کدنویسی شما به یک سوم تا نصف تبدیل میشود)، بسیار مختصر است و پیاده سازی prototype aliases و classes به سادگی و با حداقل کدنویسی انجام میگیرد.
CoffeeScript زیرمجموعهای از جاوااسکریپت نیست، اگرچه از کتابخانههای خارجی جاوااسکریپت میتوان در کدهای CoffeeScript استفاده کرد، اما برای اینکار باید کدهای مورد نیاز را به CoffeeScript تبدیل کرد تا از خطای زمان کامپایل جلوگیری شود.
پیش نیاز نوشتن کد به زبان CoffeeScript، شناخت جاوااسکریپت است تا بتوان خطاهای زمان اجرا را اصلاح کرد.
CoffeeScript محدودیتی در مرورگر ندارد و میتوان در برنامههای جاوااسکریپتی تحت سرور مانند Node.js با کیفیت بالا نیز از آن استفاده کرد.
زمانی را که برای یادگیری CoffeeScript صرف میکنید در زمان نوشتن پروژه، نتیجهی آنرا متوجه خواهید شد.
راه اندازی اولیه
یکی از سادهترین راههای نوشتن CoffeeScript استفاده از نسخهی مرورگر این زبان است و برای اینکار باید وارد سایت CoffeeScript.Org شده و بر روی تب Try CoffeeScript کلیک کنید. این سایت از نسخهی مرورگر CoffeeScript Compiler استفاده میکند و هر کدی CoffeeScript ایی که در پنل سمت چپ سایت بنویسید، تبدیل به جاوااسکریپت میشود و در پنل راست سایت، نمایش داده میشود.
همچنین میتوانید با استفاده از پروژهی js2coffee کدهای جاوااسکریپت را به کدهای CoffeeScript تبدیل کنید.
در صورتیکه بخواهید از نسخهی درون مرورگری CoffeeScript Compiler استفاده کنید، باید یک تگ اسکریپت لینک به این اسکریپت و با اضافه کردن تگ اسکریپت با type coffeescript این کار را انجام دهید. برای نمونه:
<script src="http://jashkenas.github.com/coffee-script/extras/coffee-script.js" type="text/javascript" charset="utf-8"></script> <script type="text/coffeescript"> # Some CoffeeScript </script>
برای نصب باید آخرین نسخهی Node.js و (npm (Node Package Manager را نصب کرده باشید. برای نصب CoffeeScript با استفاده از npm از دستور زیر استفاده کنید.
npm install -g coffee-script
coffee --compile my-script.coffee