استفاده از AJAX بدون نوشتن کد جاوا اسکریپت در MVC

دوشنبه 30 بهمن 1396

اگر شما نحوه کار AJAX را دوست دارید، اما ترجیحا نمی‌خواهید خودتان جاوااسکریپت را بنویسید، یک فرصت خوب در اختیار دارید؛ ASP.NET MVC دو ابزار ارائه می‌دهد که کدهای سمت کلاینت را برای‌تان می‌نویسد.

استفاده از AJAX بدون نوشتن کد جاوا اسکریپت در MVC

برنامه‌های AJAX نه تنها جذاب هستند، بلکه برای سرور شما نیز مناسب می‌باشند. با توزیع کار بین کلاینت و سرور، تقاضا را روی منبع مشترک خود (سرور) کاهش می‌دهید، که باعث می‌شود برنامه شما مقیاس‌پذیرتر شود. به علاوه AJAX برنامه شما را از یک رویکرد انفجاری بزرگ که تمام صفحه را در یک زمان ارسال می‌کند، به مجموعه‌ای از بخش‌ها تغییر می‌دهد، که هر کدام قسمتی از پردازش را انجام می‌دهند. این مسأله به شما کمک می‌کند تا بار سرور را کاهش دهید.

در اینجا سناریوهایی داریم که دو ابزار ASP.NET MVC موجود، جاوااسکریپت را برای شما می‌نویسند. یکی از این ابزارها کد سمت سرور را جهت اعتبارسنجی اطلاعات، به محض ورود کاربر در مرورگر، فراخوانی می‌کند. ابزار دیگر وقتی کاربر روی لینک کلیک می‌کند، HTML را از سرور واکشی کرده و وارد می‌کند. این سناریوها معمولی هستند، حتی اگر نوشتن اسکریپت سمت کلاینت برای شما راحت باشد، استفاده از این ابزار، شما را از کار روی stuff سخت رها می‌کند.

نکته اول: اگر هر یک از این ابزار را دوست دارید، قبل از اینکه برای استفاده از آن عجله کنید، تنظیمات مربوط به آن را بخوانید، تنظیمات جهت تغییراتی که باید انجام دهید تا این ابزار را فعال کنید.

تنظیمات

برای استفاده از این ابزار باید مطمئن شوید که در فایل Web.config، عنصر appSettings شما این دو ورودی را دارد:

<appSettings>
  <add key="ClientValidationEnabled" value="true" />
  <add key="UnobtrusiveJavaScriptEnabled" value="true" />
</appSettings>

همچنین باید کتابخانه Microsoft.jQuery.Unobstrusive.Ajax را با استفاده از NuGet به برنامه خود اضافه کنید. در نهایت، باید کتابخانه‌های jQuery مورد نیاز را به صفحه خود اضافه کنید. این‌ها برای ما کار کردند:

<script src="~/Scripts/jquery-3.1.1.min.js"></script>
<script src="~/Scripts/jquery.validate.min.js"></script>
<script src="~/Scripts/jquery.unobtrusive-AJAX.js"></script>
<script src="~/Scripts/jquery.validate.unobtrusive.min.js"></script>

ادغام اعتبارسنجی سمت سرور

وقتی افراد وارد بخش اطلاعات در صفحه شما می‌شوند، آن‌ها نمی‌خواهند تا زمانی منتظر بمانند که روی دکمه ارسال کلیک کرده و بعد متوجه شوند که اشتباه کرده‌اند. شما می‌توانید بدون اینکه هیچ کد جاوااسکریپتی بنویسید، از طریق AJAX، بازخورد سریعی که کاربران می‌خواهند را به آن‌ها بدهید. تمام کاری که باید انجام دهید این است که Remote attribute را برای ویژگی‌های مربوطه در مدل خود بگذارید و صفحه را با ترکیبی از اکشن متد/پارشیال بنویسید.

وقتی اتربیوت Remote را به کلاس Model خود اضافه می‌کنید، باید نام اکشن متد و نام کنترلی که اکشن متد درون آن است را برای فراخوانی به آن پاس دهید و سپس ویژگی ErrorMessage اتربیوت را برای پیامی که در صورت نامعتبر بودن داده می‌خواهید نمایش دهید، تنظیم کنید. مثال زیر اتربیوت Remote را برای ویژگی FirstName قرار داده است، error message را با مقدار "Bad Name" تنظیم کرده و متد ValidateName را در کنترل Validate که برای بررسی داده‌های ورودی کاربر استفاده شده، مشخص کرده است:

Public Class Customer
   Public Property Id As Integer?
   <Remote("ValidateName", "Validate", ErrorMessage:="Bad Name")>
   Public Property FirstName As String
   '...more properties...

مرحله بعدی نوشتن متد سمت سرور است که داده‌های فیلد شما را قبول می‌کند و یک شیء JSON حاوی True (اگر داده‌ها طبق همان چیزی باشد که می‌خواهیم) یا False (اگر داده‌ها طبق آن نباشند) بازمی‌گرداند. باید به متد خود نامی را اختصاص دهید و آن را در کنترلری که با تنظیمات اتربیوت Remote مطابقت دارد قرار دهید. متد شما باید پارامتری را بگیرد که نام آن با ویژگی name در شیء مدل مطابقت داشته باشد (مایکروسافت همچنین می‌گوید که باید اتربیوت OutputCache را روی متد قرار دهید).

در اینجا یک متد ساده داریم که ویژگی FirstName را اعتبارسنجی می‌کند:

<OutputCache(Location:=OutputCacheLocation.None, NoStore:=True)>
Function ValidateName(FirstName As String) As ActionResult
  Dim result As Boolean   
  If FirstName = "Peter" Then
    result = True
  Else
    result = False
  End If
  Return Json(result, JsonRequestBehavior.AllowGet)
End Function

مرحله پایانی این است که فیلدی را برای نمایش ویژگی در View اضافه کنید، همراه با یک ValidationMessage تا پیغام خطا را نمایش دهد:

@Html.TextBoxFor(Function(m) m.FirstName)
@Html.ValidationMessageFor(Function(m) m.FirstName)

اعتبارسنجی فیلدهای ارسال شده

اگر به ویژگی‌های بیشتری از مدل برای اعتبارسنجی هر ویژگی خاص نیاز دارید، می‌توانید این‌ها را قرار دهید: فقط ویژگی AdditionalFields اتربیوت را تنظیم کنید و مقادیر را با کاما از هم جدا کنید. این مثال شامل ویژگی‌های LastName و Id در داده‌های فرستاده شده با FirstName می‌باشد:

Public Class Customer
  <Remote("ValidateName", "Validate", AdditionalFields:="LastName, Id", ErrorMessage:="Bad Name")>
  Public Property FirstName As String
  Public Property Id As Integer
  Public Property LastName As String
  '...more properties...

هشدار: لیست ویژگی‌ها در AdditionalFields باید در صفحه گنجانده شوند، اگر به صورت فیلد پنهان است هم باید در HiddenFor قرار گیرد. یک View معمولی که شامل ویژگی‌های Id و LastName است می‌تواند مانند زیر باشد:

@Html.HiddenFor(Function(m) m.Id)
FirstName: @Html.TextBoxFor(Function(m) m.FirstName)
@Html.ValidationMessageFor(Function(m) m.FirstName)
LastName: @Html.TextBoxFor(Function(m) m.LastName)

اکشن متد مربوطه باید سه پارامتر برای پذیرش ویژگی FirstName و دو AdditionalFields داشته باشد. چیزی شبیه به کد زیر خواهد شد:

Function ValidName(FirstName As String, LastName As String, Id As Integer?) As ActionResult

البته، با توجه به ویژگی‌های پاس داده شده به آن، افزایش خواهد یافت.

برخی هشدارها به مراتب در مورد زمان‌بندی هستند. کد جاوااسکریپت تولید شده توسط اتربیوت Remote کد سمت سرور را برای اولین بار که کاربر داده‌ها را تغییر داده و فیلدها را ترک می‌کند، فراخوانی می‌کند. بعد از اینکه کاربر تغییرات را ایجاد کرد، هرچند اگر به فیلدها برگردد، متد سمت سرور هر زمان که کاربر کلید را فشار دهد فراخوانی می‌شود. تمام این کارها به صورت غیرهمزمان انجام می‌شود، بنابراین یک متد اعتبارسنجی با اجرای طولانی، کاربر را منتظر نگه نمی‌دارد. با این حال، شما می‌خواهید مطمئن شوید که متدتان با سرعت اجرا می‌شود، به طوری که کاربر با هر بار فشردن کلید، بی‌درنگ بازخورد را دریافت ‌کند.

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

درج HTML از سرور

ابزار دوم AjaxHelper است. در حالی که از شیء HtmlHelper از ویژگی Html ویو خود استفاده می‌کنید، ویژگی Ajax (که دارای شیء AjaxHelper است) حداقل یک متد جالب دارد. به طور مثال، ویژگی ActionLink به شما اجازه می‌دهد HTML را با روش AJAX بازیابی کنید و هنگامی که کاربر روی لینک کلیک می‌کند آن را به صفحه بفرستید. همه آنچه که باید روی سرور بنویسید، یک اکشن متد برای بازیابی داده‌ها و یک پارشیال ویو برای تولید HTML است. در View فقط باید تعدادی پارامتر را به ActionLink متد بفرستید.

همانند اکشن لینک HtmlHelper، چهار پارامتر اول به اکشن لینک AjaxHelper متد پاس داده می‌شوند: متنی برای نمایش هایپرلینک در صفحه، نام اکشن متد برای فراخوانی، نام کنترلری که اکشن متد شما در آنجاست و شیء anonymousای که به شما اجازه می‌دهد هر پارامتری که می‌خواهید به متد سمت سرور بفرستید را مشخص کنید. پارامتر پنجم برای اکشن لینک AjaxHelper جدید است: یک شیء AjaxOptions است که ویژگی‌های آن به شما اجازه می‌دهند کوئری AJAX که برای شما تولید شده است را کنترل کنید.

باید حداقل دو ویژگی را در شیء AjaxOptions قرار دهید: UpdateTargetId که عنصری را در صفحه مشخص می کند که باید با HTML آپدیت شود و InsertionMode که مشخص می‌کند چه اتفاقی برای عناصری که آپدیت می‌شوند بیفتد.

 در اینجا مثالی وجود دارد که اکشن متد GetCustomerById را در کنترلر Customer، با ارسال ویژگی CustId مدل، فراخوانی می‌کند. وقتی HTML بازمی‌گردد، هر آنچه که درون عنصر است را با اتربیوت id ست شده در CustomerInfo جایگزین می‌کند:

@Ajax.ActionLink("Click Me", "GetCustomerById", "Customer", 
                 New With {.CustId = Model.CustId}, 
                 New AJAXOptions With {.UpdateTargetId = "CustomerInfo",                                                                                                                                     
                                       .InsertionMode = InsertionMode.Replace})
<div id="CustomerInfo" />

در سرور، نیاز به یک اکشن متد دارید که داده‌های ActionLink را بپذیرد، اطلاعات مربوطه را بازیابی کند و آن‌ها را به متد پارشیال ویو کنترلر بفرستد و مشخص کند کدام متد پارشیال ویو باید استفاده شود.

این مثال یک Id را می‌پذیرد، سپس از آن برای بازیابی شیء Customer استفاده می‌کند. بعد به متد پارشیال ویو پاس داده می‌شود و پارشیال ویو CustInfo را مشخص می‌کند:

Function GetCustomerInfo(Id As Integer) As ActionResult
  Dim cust As Customer
  Using db As New CustomerOrdersContext
    cust = db.Customers.Where(Function(c) c.Id = Id).FirstOrDefault
    Return PartialView("CustInfo", cust)
  End Using
End Function

ویو CustInfo می‌تواند چیزی شبیه به کد زیر باشد:

@ModelType CustomerOrders.Customer
<dt>@Html.DisplayNameFor(Function(model) model.FirstName)</dt>
<dd>@Html.DisplayFor(Function(model) model.FirstName)</dd>
<dt>@Html.DisplayNameFor(Function(model) model.LastName)</dt>
<dd>@Html.DisplayFor(Function(model) model.LastName) </dd>

یک سری از این لینک‌ها (مثلا، یکی برای هر مشتری) به کاربر اجازه می‌دهد تا از نمایش یک customer به customer دیگر در عنصر div مربوط به CustomerInfo جابه‌جا شود، بدون هیچ جاوااسکریپتی.

بیشتر در مورد متد ActionLink گفته شد. شما همچنین می‌توانید توابع جاوااسکریپت را برای اجرا قبل و بعد از تولید کد مشخص کنید، اما حالا به نوشتن جاوااسکریپت برمی‌گردید. اگر بیش از یک تگ anchor می‌خواهید، BeginForm AjaxHelper  تمام داده‌های فرم شما را به اکشن متد به عنوان درخواست AJAX ارسال می‌کند، نه فقط یک تگ anchor تنها را.

با استفاده از این ابزارها می‌توانید برخی از وظایف مربوط به AJAX را بدون نوشتن هیچ کد جاوااسکریپتی انجام دهید. صرف نظر از اینکه خودتان می‌خواهید تولیدکننده‌های بیشتری را ایجاد کنید یا فقط اینکه جاوااسکریپت را دوست ندارید، این ابزارها بسیار باارزش هستند.

برنامه نویسان

نویسنده 3355 مقاله در برنامه نویسان

کاربرانی که از نویسنده این مقاله تشکر کرده اند

در صورتی که در رابطه با این مقاله سوالی دارید، در تاپیک های انجمن مطرح کنید