Bagikan melalui


Iterasi #7 – Tambahkan fungsionalitas Ajax (C#)

oleh Microsoft

Unduh Kode

Dalam iterasi ketujuh, kami meningkatkan responsivitas dan performa aplikasi kami dengan menambahkan dukungan untuk Ajax.

Membangun Manajemen Kontak ASP.NET Aplikasi MVC (C#)

Dalam rangkaian tutorial ini, kami membangun seluruh aplikasi Manajemen Kontak dari awal hingga akhir. Aplikasi Contact Manager memungkinkan Anda menyimpan informasi kontak - nama, nomor telepon, dan alamat email - untuk daftar orang.

Kami membangun aplikasi melalui beberapa iterasi. Dengan setiap iterasi, kami secara bertahap meningkatkan aplikasi. Tujuan dari pendekatan perulangan ganda ini adalah untuk memungkinkan Anda memahami alasan setiap perubahan.

  • Iterasi #1 - Buat aplikasi. Pada iterasi pertama, kami membuat Contact Manager dengan cara yang paling sederhana. Kami menambahkan dukungan untuk operasi database dasar: Buat, Baca, Perbarui, dan Hapus (CRUD).

  • Iterasi #2 - Buat aplikasi terlihat bagus. Dalam perulangan ini, kami meningkatkan tampilan aplikasi dengan memodifikasi halaman master tampilan ASP.NET MVC default dan lembar gaya bertingkat.

  • Iterasi #3 - Tambahkan validasi formulir. Dalam iterasi ketiga, kami menambahkan validasi formulir dasar. Kami mencegah orang mengirimkan formulir tanpa melengkapi bidang formulir yang diperlukan. Kami juga memvalidasi alamat email dan nomor telepon.

  • Iterasi #4 - Buat aplikasi digabungkan secara longgar. Dalam iterasi keempat ini, kami memanfaatkan beberapa pola desain perangkat lunak untuk mempermudah pemeliharaan dan modifikasi aplikasi Contact Manager. Misalnya, kami merefaktor aplikasi kami untuk menggunakan pola Repositori dan pola Injeksi Dependensi.

  • Iterasi #5 - Membuat pengujian unit. Dalam iterasi kelima, kami membuat aplikasi kami lebih mudah dirawat dan dimodifikasi dengan menambahkan pengujian unit. Kami meniru kelas model data kami dan membangun pengujian unit untuk pengontrol dan logika validasi kami.

  • Iterasi #6 - Gunakan pengembangan berbasis pengujian. Dalam iterasi keenam ini, kami menambahkan fungsionalitas baru ke aplikasi kami dengan menulis pengujian unit terlebih dahulu dan menulis kode terhadap pengujian unit. Dalam perulangan ini, kami menambahkan grup kontak.

  • Iterasi #7 - Tambahkan fungsionalitas Ajax. Dalam iterasi ketujuh, kami meningkatkan responsivitas dan performa aplikasi kami dengan menambahkan dukungan untuk Ajax.

Perulangan ini

Dalam iterasi aplikasi Contact Manager ini, kami merefaktor aplikasi kami untuk menggunakan Ajax. Dengan memanfaatkan Ajax, kami membuat aplikasi kami lebih responsif. Kita dapat menghindari penyajian seluruh halaman ketika kita hanya perlu memperbarui wilayah tertentu di halaman.

Kami akan merefaktor tampilan Indeks kami sehingga kami tidak perlu memutar ulang seluruh halaman setiap kali seseorang memilih grup kontak baru. Sebaliknya, ketika seseorang mengklik grup kontak, kami hanya akan memperbarui daftar kontak dan membiarkan sisa halaman saja.

Kami juga akan mengubah cara kerja tautan penghapusan kami. Alih-alih menampilkan halaman konfirmasi terpisah, kami akan menampilkan dialog konfirmasi JavaScript. Jika Anda mengonfirmasi bahwa Anda ingin menghapus kontak, operasi HTTP DELETE dilakukan terhadap server untuk menghapus rekaman kontak dari database.

Selain itu, kami akan memanfaatkan jQuery untuk menambahkan efek animasi ke tampilan Indeks kami. Kita akan menampilkan animasi ketika daftar kontak baru sedang diambil dari server.

Terakhir, kami akan memanfaatkan dukungan kerangka kerja AJAX ASP.NET untuk mengelola riwayat browser. Kami akan membuat titik riwayat setiap kali kami melakukan panggilan Ajax untuk memperbarui daftar kontak. Dengan begitu, tombol browser mundur dan maju akan berfungsi.

Mengapa menggunakan Ajax?

Menggunakan Ajax memiliki banyak manfaat. Pertama, menambahkan fungsionalitas Ajax ke aplikasi menghasilkan pengalaman pengguna yang lebih baik. Dalam aplikasi web normal, seluruh halaman harus diposting kembali ke server masing-masing dan setiap kali pengguna melakukan tindakan. Setiap kali Anda melakukan tindakan, browser mengunci dan pengguna harus menunggu sampai seluruh halaman diambil dan diputar ulang.

Ini akan menjadi pengalaman yang tidak dapat diterima dalam kasus aplikasi desktop. Tetapi, secara tradisional, kami hidup dengan pengalaman pengguna yang buruk ini dalam kasus aplikasi web karena kami tidak tahu bahwa kami bisa melakukan yang lebih baik. Kami pikir itu adalah batasan aplikasi web ketika, pada kenyataannya, itu hanya batasan imajinasi kami.

Dalam aplikasi Ajax, Anda tidak perlu membawa pengalaman pengguna berhenti hanya untuk memperbarui halaman. Sebagai gantinya, Anda dapat melakukan permintaan asinkron di latar belakang untuk memperbarui halaman. Anda tidak memaksa pengguna untuk menunggu sementara bagian dari halaman diperbarui.

Dengan memanfaatkan Ajax, Anda juga dapat meningkatkan performa aplikasi Anda. Pertimbangkan cara kerja aplikasi Contact Manager saat ini tanpa fungsionalitas Ajax. Saat Anda mengklik grup kontak, seluruh tampilan Indeks harus diputar ulang. Daftar kontak dan daftar grup kontak harus diambil dari server database. Semua data ini harus diteruskan di seluruh kawat dari server web ke browser web.

Namun, setelah kami menambahkan fungsionalitas Ajax ke aplikasi kami, kami dapat menghindari pemutaran ulang seluruh halaman saat pengguna mengklik grup kontak. Kita tidak perlu lagi mengambil grup kontak dari database. Kita juga tidak perlu mendorong seluruh tampilan Indeks di seluruh kabel. Dengan memanfaatkan Ajax, kami mengurangi jumlah pekerjaan yang harus dilakukan server database kami dan kami mengurangi jumlah lalu lintas jaringan yang diperlukan oleh aplikasi kami.

Jangan Takut Ajax

Beberapa pengembang menghindari penggunaan Ajax karena mereka khawatir tentang browser tingkat bawah. Mereka ingin memastikan bahwa aplikasi web mereka masih akan berfungsi ketika diakses oleh browser yang tidak mendukung JavaScript. Karena Ajax bergantung pada JavaScript, beberapa pengembang menghindari penggunaan Ajax.

Namun, jika Anda berhati-hati tentang bagaimana Anda mengimplementasikan Ajax maka Anda dapat membangun aplikasi yang bekerja dengan browser uplevel dan downlevel. Aplikasi Contact Manager kami akan berfungsi dengan browser yang mendukung JavaScript dan browser yang tidak.

Jika Anda menggunakan aplikasi Contact Manager dengan browser yang mendukung JavaScript maka Anda akan memiliki pengalaman pengguna yang lebih baik. Misalnya, saat Anda mengklik grup kontak, hanya wilayah halaman yang menampilkan kontak yang akan diperbarui.

Jika, di sisi lain, Anda menggunakan aplikasi Contact Manager dengan browser yang tidak mendukung JavaScript (atau yang menonaktifkan JavaScript) maka Anda akan memiliki pengalaman pengguna yang sedikit kurang diinginkan. Misalnya, saat Anda mengklik grup kontak, seluruh tampilan Indeks harus diposting kembali ke browser untuk menampilkan daftar kontak yang cocok.

Menambahkan File JavaScript yang Diperlukan

Kita harus menggunakan tiga file JavaScript untuk menambahkan fungsionalitas Ajax ke aplikasi kita. Ketiga file ini disertakan dalam folder Skrip dari aplikasi ASP.NET MVC baru.

Jika Anda berencana menggunakan Ajax di beberapa halaman di aplikasi Anda, maka masuk akal untuk menyertakan file JavaScript yang diperlukan di halaman master tampilan aplikasi Anda. Dengan begitu, file JavaScript akan disertakan di semua halaman dalam aplikasi Anda secara otomatis.

Tambahkan JavaScript berikut ini termasuk di dalam <tag kepala> halaman master tampilan Anda:

<script src="../../Scripts/MicrosoftAjax.js" type="text/javascript"></script>
    <script src="../../Scripts/MicrosoftMvcAjax.js" type="text/javascript"></script>
    <script src="../../Scripts/jquery-1.2.6.min.js" type="text/javascript"></script>

Merefaktor Tampilan Indeks untuk menggunakan Ajax

Mari kita mulai dengan memodifikasi tampilan Indeks kita sehingga mengklik grup kontak hanya memperbarui wilayah tampilan yang menampilkan kontak. Kotak merah di Gambar 1 berisi wilayah yang ingin kami perbarui.

Memperbarui kontak saja

Gambar 01: Memperbarui hanya kontak (Klik untuk melihat gambar ukuran penuh)

Langkah pertama adalah memisahkan bagian tampilan yang ingin kami perbarui secara asinkron menjadi parsial terpisah (lihat kontrol pengguna). Bagian tampilan Indeks yang menampilkan tabel kontak telah dipindahkan ke parsial di Daftar 1.

Daftar 1 - Views\Contact\ContactList.ascx

<%@ Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl<ContactManager.Models.Group>" %>
<%@ Import Namespace="Helpers" %>
<table class="data-table" cellpadding="0" cellspacing="0">
    <thead>
        <tr>
            <th class="actions edit">
                Edit
            </th>
            <th class="actions delete">
                Delete
            </th>
            <th>
                Name
            </th>
            <th>
                Phone
            </th>
            <th>
                Email
            </th>
        </tr>
    </thead>
    <tbody>
        <% foreach (var item in Model.Contacts)
           { %>
        <tr>
            <td class="actions edit">
                <a href='<%= Url.Action("Edit", new {id=item.Id}) %>'><img src="../../Content/Edit.png" alt="Edit" /></a>
            </td>
            <td class="actions delete">
                <a href='<%= Url.Action("Delete", new {id=item.Id}) %>'><img src="../../Content/Delete.png" alt="Edit" /></a>
            </td>
            <th>
                <%= Html.Encode(item.FirstName) %>
                <%= Html.Encode(item.LastName) %>
            </th>
            <td>
                <%= Html.Encode(item.Phone) %>
            </td>
            <td>
                <%= Html.Encode(item.Email) %>
            </td>
        </tr>
        <% } %>
    </tbody>
</table>

Perhatikan bahwa parsial dalam Daftar 1 memiliki model yang berbeda dari tampilan Indeks. Atribut Mewarisi di <direktif %@ Page %> menentukan bahwa sebagian mewarisi dari kelas ViewUserControl<Group> .

Tampilan Indeks yang diperbarui terkandung dalam Daftar 2.

Daftar 2 - Views\Contact\Index.aspx

<%@ Page Title="" Language="C#" MasterPageFile="~/Views/Shared/Site.Master" Inherits="System.Web.Mvc.ViewPage<ContactManager.Models.ViewData.IndexModel>" %>
<%@ Import Namespace="Helpers" %>
<asp:Content ID="Content1" ContentPlaceHolderID="head" runat="server">
<title>Index</title>
</asp:Content>

<asp:Content ID="Content2" ContentPlaceHolderID="MainContent" runat="server">

<ul id="leftColumn">
<% foreach (var item in Model.Groups) { %>
    <li <%= Html.Selected(item.Id, Model.SelectedGroup.Id) %>>
    <%= Ajax.ActionLink(item.Name, "Index", new { id = item.Id }, new AjaxOptions { UpdateTargetId = "divContactList"})%>
    </li>
<% } %>
</ul>
<div id="divContactList">
    <% Html.RenderPartial("ContactList", Model.SelectedGroup); %>
</div>

<div class="divContactList-bottom"> </div>
</asp:Content>

Ada dua hal yang harus Anda perhatikan tentang tampilan yang diperbarui di Daftar 2. Pertama, perhatikan bahwa semua konten yang dipindahkan ke parsial diganti dengan panggilan ke Html.RenderPartial(). Metode Html.RenderPartial() dipanggil ketika tampilan Indeks pertama kali diminta untuk menampilkan kumpulan kontak awal.

Kedua, perhatikan bahwa Html.ActionLink() yang digunakan untuk menampilkan grup kontak telah diganti dengan Ajax.ActionLink(). Ajax.ActionLink() dipanggil dengan parameter berikut:

<%= Ajax.ActionLink(item.Name, "Index", new { id = item.Id }, new AjaxOptions { UpdateTargetId = "divContactList"})%>

Parameter pertama mewakili teks yang akan ditampilkan untuk tautan, parameter kedua mewakili nilai rute, dan parameter ketiga mewakili opsi Ajax. Dalam hal ini, kami menggunakan opsi UpdateTargetId Ajax untuk menunjuk ke tag div> HTML <yang ingin kami perbarui setelah permintaan Ajax selesai. Kami ingin memperbarui tag div <> dengan daftar kontak baru.

Metode Index() yang diperbarui dari pengontrol Kontak terkandung dalam Daftar 3.

Daftar 3 - Controllers\ContactController.cs (Metode indeks)

public ActionResult Index(int? id)
{
    // Get selected group
    var selectedGroup = _service.GetGroup(id);
    if (selectedGroup == null)
        return RedirectToAction("Index", "Group");

    // Normal Request
    if (!Request.IsAjaxRequest())
    {
        var model = new IndexModel
        {
            Groups = _service.ListGroups(),
            SelectedGroup = selectedGroup
        };
        return View("Index", model);
    }

    // Ajax Request
    return PartialView("ContactList", selectedGroup);
}

Tindakan Index() yang diperbarui secara kondisional mengembalikan salah satu dari dua hal. Jika tindakan Index() dipanggil oleh permintaan Ajax, maka pengontrol mengembalikan sebagian. Jika tidak, tindakan Index() mengembalikan seluruh tampilan.

Perhatikan bahwa tindakan Index() tidak perlu mengembalikan data sebanyak saat dipanggil oleh permintaan Ajax. Dalam konteks permintaan normal, tindakan Indeks mengembalikan daftar semua grup kontak dan grup kontak yang dipilih. Dalam konteks permintaan Ajax, tindakan Index() hanya mengembalikan grup yang dipilih. Ajax berarti lebih sedikit pekerjaan di server database Anda.

Tampilan Indeks kami yang dimodifikasi berfungsi dalam kasus browser uplevel dan downlevel. Jika Anda mengklik grup kontak, dan browser Anda mendukung JavaScript, maka hanya wilayah tampilan yang berisi daftar kontak yang diperbarui. Jika, di sisi lain, browser Anda tidak mendukung JavaScript, maka seluruh tampilan diperbarui.

Tampilan Indeks kami yang diperbarui memiliki satu masalah. Saat Anda mengklik grup kontak, grup yang dipilih tidak disorot. Karena daftar grup ditampilkan di luar wilayah yang diperbarui selama permintaan Ajax, grup yang tepat tidak disorot. Kami akan memperbaiki masalah ini di bagian berikutnya.

Menambahkan Efek Animasi jQuery

Biasanya, ketika Anda mengklik tautan di halaman web, Anda dapat menggunakan bilah kemajuan browser untuk mendeteksi apakah browser secara aktif mengambil konten yang diperbarui atau tidak. Saat melakukan permintaan Ajax, di sisi lain, bilah kemajuan browser tidak menunjukkan kemajuan apa pun. Hal ini dapat membuat pengguna gugup. Bagaimana Anda tahu apakah browser telah membeku?

Ada beberapa cara yang dapat Anda tunjukkan kepada pengguna bahwa pekerjaan sedang dilakukan saat melakukan permintaan Ajax. Salah satu pendekatannya adalah menampilkan animasi sederhana. Misalnya, Anda dapat memudarkan wilayah saat permintaan Ajax dimulai dan memudar di wilayah saat permintaan selesai.

Kita akan menggunakan pustaka jQuery yang disertakan dengan kerangka kerja Microsoft ASP.NET MVC, untuk membuat efek animasi. Tampilan Indeks yang diperbarui terkandung dalam Daftar 4.

Daftar 4 - Views\Contact\Index.aspx

<%@ Page Title="" Language="C#" MasterPageFile="~/Views/Shared/Site.Master" Inherits="System.Web.Mvc.ViewPage<ContactManager.Models.ViewData.IndexModel>" %>
<%@ Import Namespace="Helpers" %>
<asp:Content ID="Content1" ContentPlaceHolderID="head" runat="server">
<title>Index</title>
</asp:Content>

<asp:Content ID="Content2" ContentPlaceHolderID="MainContent" runat="server">

<script type="text/javascript">

    function beginContactList(args) {
        // Highlight selected group
        $('#leftColumn li').removeClass('selected');
        $(this).parent().addClass('selected');

        // Animate
        $('#divContactList').fadeOut('normal');
    }

    function successContactList() {
        // Animate
        $('#divContactList').fadeIn('normal');
    }

    function failureContactList() {
        alert("Could not retrieve contacts.");
    }

</script>

<ul id="leftColumn">
<% foreach (var item in Model.Groups) { %>
    <li <%= Html.Selected(item.Id, Model.SelectedGroup.Id) %>>
    <%= Ajax.ActionLink(item.Name, "Index", new { id = item.Id }, new AjaxOptions { UpdateTargetId = "divContactList", OnBegin = "beginContactList", OnSuccess = "successContactList", OnFailure = "failureContactList" })%>
    </li>
<% } %>
</ul>
<div id="divContactList">
    <% Html.RenderPartial("ContactList", Model.SelectedGroup); %>
</div>

<div class="divContactList-bottom"> </div>
</asp:Content>

Perhatikan bahwa tampilan Indeks yang diperbarui berisi tiga fungsi JavaScript baru. Dua fungsi pertama menggunakan jQuery untuk memudar dan memudar dalam daftar kontak saat Anda mengklik grup kontak baru. Fungsi ketiga menampilkan pesan kesalahan saat permintaan Ajax menghasilkan kesalahan (misalnya, batas waktu jaringan).

Fungsi pertama juga mengurus penyorotan grup yang dipilih. Kelas= atribut yang dipilih ditambahkan ke elemen induk (elemen LI) dari elemen yang diklik. Sekali lagi, jQuery memudahkan untuk memilih elemen yang tepat dan menambahkan kelas CSS.

Skrip ini terkait dengan tautan grup dengan bantuan parameter Ajax.ActionLink() AjaxOptions. Panggilan metode Ajax.ActionLink() yang diperbarui terlihat seperti ini:

<%= Ajax.ActionLink(item.Name, "Index", new { id = item.Id }, new AjaxOptions { UpdateTargetId = "divContactList", OnBegin = "beginContactList", OnSuccess = "successContactList", OnFailure = "failureContactList" })%>

Menambahkan Dukungan Riwayat Browser

Biasanya, ketika Anda mengklik tautan untuk memperbarui halaman, riwayat browser Anda diperbarui. Dengan begitu, Anda dapat mengklik tombol Kembali browser untuk kembali ke keadaan halaman sebelumnya. Misalnya, jika Anda mengklik grup kontak Teman lalu mengklik grup kontak Bisnis, Anda dapat mengklik tombol Kembali browser untuk menavigasi kembali ke status halaman saat grup kontak Teman dipilih.

Sayangnya, melakukan permintaan Ajax tidak memperbarui riwayat browser secara otomatis. Jika Anda mengklik grup kontak, dan daftar kontak yang cocok diambil dengan permintaan Ajax, maka riwayat browser tidak diperbarui. Anda tidak dapat menggunakan tombol Kembali browser untuk menavigasi kembali ke grup kontak setelah memilih grup kontak baru.

Jika Anda ingin pengguna dapat menggunakan tombol Kembali browser setelah melakukan permintaan Ajax maka Anda perlu melakukan sedikit lebih banyak pekerjaan. Anda perlu memanfaatkan fungsionalitas manajemen riwayat browser yang dibangun di ASP.NET AJAX Framework.

ASP.NET riwayat browser AJAX, Anda perlu melakukan tiga hal:

  1. Aktifkan Riwayat Browser dengan mengatur properti enableBrowserHistory ke true.
  2. Simpan titik riwayat saat status tampilan berubah dengan memanggil metode addHistoryPoint().
  3. Merekonstruksi status tampilan saat peristiwa navigasi dinaikkan.

Tampilan Indeks yang diperbarui terkandung dalam Daftar 5.

Daftar 5 - Views\Contact\Index.aspx

<%@ Page Title="" Language="C#" MasterPageFile="~/Views/Shared/Site.Master" Inherits="System.Web.Mvc.ViewPage<ContactManager.Models.ViewData.IndexModel>" %>
<%@ Import Namespace="Helpers" %>
<asp:Content ID="Content1" ContentPlaceHolderID="head" runat="server">
<title>Index</title>
</asp:Content>

<asp:Content ID="Content2" ContentPlaceHolderID="MainContent" runat="server">

<script type="text/javascript">

    var _currentGroupId = -1;

    Sys.Application.add_init(pageInit);

    function pageInit() {
        // Enable history
        Sys.Application.set_enableHistory(true);

        // Add Handler for history
        Sys.Application.add_navigate(navigate);
    }

    function navigate(sender, e) {
        // Get groupId from address bar
        var groupId = e.get_state().groupId;

        // If groupId != currentGroupId then navigate
        if (groupId != _currentGroupId) {
            _currentGroupId = groupId;
            $("#divContactList").load("/Contact/Index/" + groupId);
            selectGroup(groupId);
        }
    }

    function selectGroup(groupId) {
        $('#leftColumn li').removeClass('selected');
        if (groupId)
            $('a[groupid=' + groupId + ']').parent().addClass('selected');
        else
            $('#leftColumn li:first').addClass('selected');
    }

    function beginContactList(args) {
        // Highlight selected group
        _currentGroupId = this.getAttribute("groupid");
        selectGroup(_currentGroupId);

        // Add history point
        Sys.Application.addHistoryPoint({ "groupId": _currentGroupId });

        // Animate
        $('#divContactList').fadeOut('normal');
    }

    function successContactList() {
        // Animate
        $('#divContactList').fadeIn('normal');
    }

    function failureContactList() {
        alert("Could not retrieve contacts.");
    }

</script>

<ul id="leftColumn">
<% foreach (var item in Model.Groups) { %>
    <li <%= Html.Selected(item.Id, Model.SelectedGroup.Id) %>>
    <%= Ajax.ActionLink(item.Name, "Index", new { id = item.Id }, new AjaxOptions { UpdateTargetId = "divContactList", OnBegin = "beginContactList", OnSuccess = "successContactList", OnFailure = "failureContactList" }, new { groupid = item.Id })%>
    </li>
<% } %>
</ul>
<div id="divContactList">
    <% Html.RenderPartial("ContactList", Model.SelectedGroup); %>
</div>

<div class="divContactList-bottom"> </div>
</asp:Content>

Di Daftar 5, Riwayat Browser diaktifkan dalam fungsi pageInit(). Fungsi pageInit() juga digunakan untuk menyiapkan penanganan aktivitas untuk acara navigasi. Peristiwa navigasi dinaikkan setiap kali tombol Teruskan atau Kembali browser menyebabkan status halaman berubah.

Metode beginContactList() dipanggil saat Anda mengklik grup kontak. Metode ini membuat titik riwayat baru dengan memanggil metode addHistoryPoint(). Id grup kontak yang diklik ditambahkan ke riwayat.

Id grup diambil dari atribut expando pada tautan grup kontak. Tautan dirender dengan panggilan berikut ke Ajax.ActionLink().

<%= Ajax.ActionLink(item.Name, "Index", new { id = item.Id }, new AjaxOptions { UpdateTargetId = "divContactList", OnBegin = "beginContactList", OnSuccess = "successContactList", OnFailure = "failureContactList" }, new {groupid=item.Id})%>

Parameter terakhir yang diteruskan ke Ajax.ActionLink() menambahkan atribut expando bernama groupid ke tautan (huruf kecil untuk kompatibilitas XHTML).

Saat pengguna menekan tombol Kembali atau Teruskan browser, peristiwa navigasi dinaikkan dan metode navigate() dipanggil. Metode ini memperbarui kontak yang ditampilkan di halaman agar sesuai dengan status halaman yang sesuai dengan titik riwayat browser yang diteruskan ke metode navigasi.

Melakukan Penghapusan Ajax

Saat ini, untuk menghapus kontak, Anda perlu mengklik tautan Hapus lalu klik tombol Hapus yang ditampilkan di halaman konfirmasi penghapusan (lihat Gambar 2). Ini tampaknya seperti banyak permintaan halaman untuk melakukan sesuatu yang sederhana seperti menghapus rekaman database.

Halaman konfirmasi penghapusan

Gambar 02: Halaman konfirmasi penghapusan (Klik untuk melihat gambar ukuran penuh)

Sangat menggoda untuk melewati halaman konfirmasi penghapusan dan menghapus kontak langsung dari tampilan Indeks. Anda harus menghindari godaan ini karena mengambil pendekatan ini membuka aplikasi Anda ke lubang keamanan. Secara umum, Anda tidak ingin melakukan operasi HTTP GET saat memanggil tindakan yang memodifikasi status aplikasi web Anda. Saat melakukan penghapusan, Anda ingin melakukan HTTP POST, atau lebih baik lagi, operasi HTTP DELETE.

Tautan Hapus terkandung dalam sebagian ContactList. Versi terbaru dari parsial ContactList terkandung dalam Daftar 6.

Daftar 6 - Views\Contact\ContactList.ascx

<%@ Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl<ContactManager.Models.Group>" %>
<%@ Import Namespace="Helpers" %>
<table class="data-table" cellpadding="0" cellspacing="0">
    <thead>
        <tr>
            <th class="actions edit">
                Edit
            </th>
            <th class="actions delete">
                Delete
            </th>
            <th>
                Name
            </th>
            <th>
                Phone
            </th>
            <th>
                Email
            </th>
        </tr>
    </thead>
    <tbody>
        <% foreach (var item in Model.Contacts)
           { %>
        <tr>
            <td class="actions edit">
                <a href='<%= Url.Action("Edit", new {id=item.Id}) %>'><img src="../../Content/Edit.png" alt="Edit" /></a>
            </td>
            <td class="actions delete">
            <%= Ajax.ImageActionLink("../../Content/Delete.png", "Delete", "Delete", new { id = item.Id }, new AjaxOptions { Confirm = "Delete contact?", HttpMethod = "Delete", UpdateTargetId = "divContactList" })%> 
            </td>
            <th>
                <%= Html.Encode(item.FirstName) %>
                <%= Html.Encode(item.LastName) %>
            </th>
            <td>
                <%= Html.Encode(item.Phone) %>
            </td>
            <td>
                <%= Html.Encode(item.Email) %>
            </td>
        </tr>
        <% } %>
    </tbody>
</table>

Tautan Hapus dirender dengan panggilan berikut ke metode Ajax.ImageActionLink():

<%= Ajax.ImageActionLink("../../Content/Delete.png", "Delete", "Delete", new { id = item.Id }, new AjaxOptions { Confirm = "Delete contact?", HttpMethod = "Delete", UpdateTargetId = "divContactList" })%>

Catatan

Ajax.ImageActionLink() bukan bagian standar dari kerangka kerja MVC ASP.NET. Ajax.ImageActionLink() adalah metode pembantu kustom yang disertakan dalam proyek Contact Manager.

Parameter AjaxOptions memiliki dua properti. Pertama, properti Konfirmasi digunakan untuk menampilkan dialog konfirmasi Popup JavaScript. Kedua, properti HttpMethod digunakan untuk melakukan operasi HTTP DELETE.

Daftar 7 berisi tindakan AjaxDelete() baru yang telah ditambahkan ke pengontrol Kontak.

Daftar 7 - Pengontrol\ContactController.cs (AjaxDelete)

[AcceptVerbs(HttpVerbs.Delete)]
[ActionName("Delete")]
public ActionResult AjaxDelete(int id)
{
    // Get contact and group
    var contactToDelete = _service.GetContact(id);
    var selectedGroup = _service.GetGroup(contactToDelete.Group.Id);

    // Delete from database
    _service.DeleteContact(contactToDelete);

    // Return Contact List
    return PartialView("ContactList", selectedGroup);
}

Tindakan AjaxDelete() dihiasi dengan atribut AcceptVerbs. Atribut ini mencegah tindakan dipanggil kecuali oleh operasi HTTP selain operasi HTTP DELETE. Secara khusus, Anda tidak dapat memanggil tindakan ini dengan HTTP GET.

Setelah Anda menghapus rekaman database, Anda perlu menampilkan daftar kontak yang diperbarui yang tidak berisi rekaman yang dihapus. Metode AjaxDelete() mengembalikan sebagian ContactList dan daftar kontak yang diperbarui.

Ringkasan

Dalam iterasi ini, kami menambahkan fungsionalitas Ajax ke aplikasi Contact Manager kami. Kami menggunakan Ajax untuk meningkatkan responsivitas dan performa aplikasi kami.

Pertama, kami merefaktor tampilan Indeks sehingga mengklik grup kontak tidak memperbarui seluruh tampilan. Sebagai gantinya, mengklik grup kontak hanya memperbarui daftar kontak.

Selanjutnya, kami menggunakan efek animasi jQuery untuk memudar dan memudar dalam daftar kontak. Menambahkan animasi ke aplikasi Ajax dapat digunakan untuk memberi pengguna aplikasi dengan bilah kemajuan browser yang setara.

Kami juga menambahkan dukungan riwayat browser ke aplikasi Ajax kami. Kami mengaktifkan pengguna untuk mengklik tombol Kembali dan Teruskan browser untuk mengubah status tampilan Indeks.

Terakhir, kami membuat tautan hapus yang mendukung operasi HTTP DELETE. Dengan melakukan penghapusan Ajax, kami memungkinkan pengguna untuk menghapus rekaman database tanpa mengharuskan pengguna untuk meminta halaman konfirmasi penghapusan tambahan.