Aracılığıyla paylaş


Bölüm 8: Ajax Güncelleştirmeleriyle Alışveriş Sepeti

tarafından Jon Galloway

MVC Müzik Deposu, web geliştirme için ASP.NET MVC ve Visual Studio'yu kullanmayı adım adım tanıtır ve açıklayan bir öğretici uygulamasıdır.

MVC Music Store, müzik albümlerini çevrimiçi olarak satan ve temel site yönetimi, kullanıcı oturum açma ve alışveriş sepeti işlevlerini uygulayan basit bir örnek mağaza uygulamasıdır.

Bu öğretici serisi, ASP.NET MVC Müzik Deposu örnek uygulamasını derlemek için atılan tüm adımların ayrıntılarını içerir. Bölüm 8, Ajax Güncelleştirmeler ile Alışveriş Sepetini kapsar.

Kullanıcıların kayıt yapmadan albümleri sepetlerine yerleştirmelerine izin vereceğiz, ancak alışverişi tamamlamak için konuk olarak kaydolmaları gerekir. Alışveriş ve ödeme işlemi iki denetleyiciye ayrılacak: bir sepete anonim olarak öğe eklemeye izin veren bir ShoppingCart Denetleyicisi ve ödeme işlemini gerçekleştiren bir Kullanıma Alma Denetleyicisi. Bu bölümde Alışveriş Sepeti ile başlayacağız, ardından aşağıdaki bölümde Kullanıma Alma işlemini oluşturacağız.

Cart, Order ve OrderDetail model sınıflarını ekleme

Alışveriş Sepeti ve Ödeme süreçlerimiz bazı yeni sınıflardan yararlanacaktır. Models klasörüne sağ tıklayın ve aşağıdaki kodla bir Cart sınıfı (Cart.cs) ekleyin.

using System.ComponentModel.DataAnnotations;
 
namespace MvcMusicStore.Models
{
    public class Cart
    {
        [Key]
        public int      RecordId    { get; set; }
        public string   CartId      { get; set; }
        public int      AlbumId     { get; set; }
        public int      Count       { get; set; }
        public System.DateTime DateCreated { get; set; }
        public virtual Album Album  { get; set; }
    }
}

Bu sınıf, RecordId özelliğinin [Key] özniteliği dışında şimdiye kadar kullandığımız diğer sınıflara oldukça benzer. Sepet öğelerimizin anonim alışverişe izin vermek için CartID adlı bir dize tanımlayıcısı olacaktır, ancak tabloda RecordId adlı bir tamsayı birincil anahtarı bulunur. Kural gereği, Entity Framework Code-First Cart adlı tablonun birincil anahtarının CartId veya ID olmasını bekler, ancak isterseniz bunu ek açıklamalar veya kod aracılığıyla kolayca geçersiz kılabiliriz. Bu, Entity Framework'teki basit kuralları bize uygun olduğunda Code-First nasıl kullanabileceğimize bir örnektir, ancak bunlar uygun olmadığında onlar tarafından kısıtlanmaz.

Ardından, aşağıdaki kodla bir Order sınıfı (Order.cs) ekleyin.

using System.Collections.Generic;
 
namespace MvcMusicStore.Models
{
    public partial class Order
    {
        public int    OrderId    { get; set; }
        public string Username   { get; set; }
        public string FirstName  { get; set; }
        public string LastName   { get; set; }
        public string Address    { get; set; }
        public string City       { get; set; }
        public string State      { get; set; }
        public string PostalCode { get; set; }
        public string Country    { get; set; }
        public string Phone      { get; set; }
        public string Email      { get; set; }
        public decimal Total     { get; set; }
        public System.DateTime OrderDate      { get; set; }
        public List<OrderDetail> OrderDetails { get; set; }
    }
}

Bu sınıf, bir siparişin özet ve teslim bilgilerini izler. Henüz oluşturmadığımız bir sınıfa bağlı olan bir OrderDetails gezinti özelliğine sahip olduğundan henüz derlenmez. Şimdi OrderDetail.cs adlı bir sınıf ekleyerek ve aşağıdaki kodu ekleyerek bunu düzeltelim.

namespace MvcMusicStore.Models
{
    public class OrderDetail
    {
        public int OrderDetailId { get; set; }
        public int OrderId { get; set; }
        public int AlbumId { get; set; }
        public int Quantity { get; set; }
        public decimal UnitPrice { get; set; }
        public virtual Album Album { get; set; }
        public virtual Order Order { get; set; }
    }
}

MusicStoreEntities sınıfımızda DbSets'i içerecek şekilde son bir güncelleştirme yapacağız. Bu güncelleştirme, dbSet<Artist> de dahil olmak üzere bu yeni Model sınıflarını kullanıma sunar. Güncelleştirilmiş MusicStoreEntities sınıfı aşağıdaki gibi görünür.

using System.Data.Entity;
 
namespace MvcMusicStore.Models
{
    public class MusicStoreEntities : DbContext
    {
        public DbSet<Album>     Albums  { get; set; }
        public DbSet<Genre>     Genres  { get; set; }
        public DbSet<Artist>    Artists {
get; set; }
        public DbSet<Cart>     
Carts { get; set; }
        public DbSet<Order>     Orders
{ get; set; }
        public DbSet<OrderDetail>
OrderDetails { get; set; }
    }
}

Alışveriş Sepeti iş mantığını yönetme

Ardından Models klasöründe ShoppingCart sınıfını oluşturacağız. ShoppingCart modeli Sepet tablosuna veri erişimini işler. Buna ek olarak, alışveriş sepetine öğe ekleme ve alışveriş sepetinden öğe kaldırmaya yönelik iş mantığını işler.

Kullanıcıların yalnızca alışveriş sepetlerine öğe eklemek için bir hesaba kaydolmalarını gerektirmek istemediğimiz için, kullanıcılara alışveriş sepetine erişirken geçici bir benzersiz tanımlayıcı (GUID veya genel olarak benzersiz tanımlayıcı kullanarak) atarız. Bu kimliği ASP.NET Session sınıfını kullanarak depolayacağız.

Not: ASP.NET Oturumu, siteden ayrıldıktan sonra süresi dolacak olan kullanıcıya özgü bilgileri depolamak için uygun bir yerdir. Oturum durumunun kötüye kullanılması daha büyük sitelerde performans açısından etkilere neden olsa da, ışık kullanımımız gösterim amacıyla iyi çalışır.

ShoppingCart sınıfı aşağıdaki yöntemleri kullanıma sunar:

AddToCart parametre olarak bir Albüm alır ve bunu kullanıcının sepetine ekler. Cart tablosu her albümün miktarını izlediğinden, gerekirse yeni bir satır oluşturma mantığı veya kullanıcı albümün bir kopyasını sipariş etmişse miktarı artırma mantığı içerir.

RemoveFromCart bir Albüm Kimliği alır ve bunu kullanıcının sepetinden kaldırır. Kullanıcının sepetinde albümün yalnızca bir kopyası varsa, satır kaldırılır.

EmptyCart kullanıcının alışveriş sepetindeki tüm öğeleri kaldırır.

GetCartItems , görüntüleme veya işleme için CartItems listesini alır.

GetCount , kullanıcının alışveriş sepetindeki toplam albüm sayısını alır.

GetTotal , sepetteki tüm öğelerin toplam maliyetini hesaplar.

CreateOrder , alışveriş sepetini ödeme aşamasında bir siparişe dönüştürür.

GetCart , denetleyicilerimizin bir sepet nesnesi almasını sağlayan statik bir yöntemdir. Kullanıcının oturumundan CartId değerini okumayı işlemek için GetCartId yöntemini kullanır. GetCartId yöntemi, kullanıcının oturumundan kullanıcının CartId değerini okuyabilmesi için HttpContextBase gerektirir.

İşte tam ShoppingCart sınıfı:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
 
namespace MvcMusicStore.Models
{
    public partial class ShoppingCart
    {
        MusicStoreEntities storeDB = new MusicStoreEntities();
        string ShoppingCartId { get; set; }
        public const string CartSessionKey = "CartId";
        public static ShoppingCart GetCart(HttpContextBase context)
        {
            var cart = new ShoppingCart();
            cart.ShoppingCartId = cart.GetCartId(context);
            return cart;
        }
        // Helper method to simplify shopping cart calls
        public static ShoppingCart GetCart(Controller controller)
        {
            return GetCart(controller.HttpContext);
        }
        public void AddToCart(Album album)
        {
            // Get the matching cart and album instances
            var cartItem = storeDB.Carts.SingleOrDefault(
                c => c.CartId == ShoppingCartId 
                && c.AlbumId == album.AlbumId);
 
            if (cartItem == null)
            {
                // Create a new cart item if no cart item exists
                cartItem = new Cart
                {
                    AlbumId = album.AlbumId,
                    CartId = ShoppingCartId,
                    Count = 1,
                    DateCreated = DateTime.Now
                };
                storeDB.Carts.Add(cartItem);
            }
            else
            {
                // If the item does exist in the cart, 
                // then add one to the quantity
                cartItem.Count++;
            }
            // Save changes
            storeDB.SaveChanges();
        }
        public int RemoveFromCart(int id)
        {
            // Get the cart
            var cartItem = storeDB.Carts.Single(
                cart => cart.CartId == ShoppingCartId 
                && cart.RecordId == id);
 
            int itemCount = 0;
 
            if (cartItem != null)
            {
                if (cartItem.Count > 1)
                {
                    cartItem.Count--;
                    itemCount = cartItem.Count;
                }
                else
                {
                    storeDB.Carts.Remove(cartItem);
                }
                // Save changes
                storeDB.SaveChanges();
            }
            return itemCount;
        }
        public void EmptyCart()
        {
            var cartItems = storeDB.Carts.Where(
                cart => cart.CartId == ShoppingCartId);
 
            foreach (var cartItem in cartItems)
            {
                storeDB.Carts.Remove(cartItem);
            }
            // Save changes
            storeDB.SaveChanges();
        }
        public List<Cart> GetCartItems()
        {
            return storeDB.Carts.Where(
                cart => cart.CartId == ShoppingCartId).ToList();
        }
        public int GetCount()
        {
            // Get the count of each item in the cart and sum them up
            int? count = (from cartItems in storeDB.Carts
                          where cartItems.CartId == ShoppingCartId
                          select (int?)cartItems.Count).Sum();
            // Return 0 if all entries are null
            return count ?? 0;
        }
        public decimal GetTotal()
        {
            // Multiply album price by count of that album to get 
            // the current price for each of those albums in the cart
            // sum all album price totals to get the cart total
            decimal? total = (from cartItems in storeDB.Carts
                              where cartItems.CartId == ShoppingCartId
                              select (int?)cartItems.Count *
                              cartItems.Album.Price).Sum();

            return total ?? decimal.Zero;
        }
        public int CreateOrder(Order order)
        {
            decimal orderTotal = 0;
 
            var cartItems = GetCartItems();
            // Iterate over the items in the cart, 
            // adding the order details for each
            foreach (var item in cartItems)
            {
                var orderDetail = new OrderDetail
                {
                    AlbumId = item.AlbumId,
                    OrderId = order.OrderId,
                    UnitPrice = item.Album.Price,
                    Quantity = item.Count
                };
                // Set the order total of the shopping cart
                orderTotal += (item.Count * item.Album.Price);
 
                storeDB.OrderDetails.Add(orderDetail);
 
            }
            // Set the order's total to the orderTotal count
            order.Total = orderTotal;
 
            // Save the order
            storeDB.SaveChanges();
            // Empty the shopping cart
            EmptyCart();
            // Return the OrderId as the confirmation number
            return order.OrderId;
        }
        // We're using HttpContextBase to allow access to cookies.
        public string GetCartId(HttpContextBase context)
        {
            if (context.Session[CartSessionKey] == null)
            {
                if (!string.IsNullOrWhiteSpace(context.User.Identity.Name))
                {
                    context.Session[CartSessionKey] =
                        context.User.Identity.Name;
                }
                else
                {
                    // Generate a new random GUID using System.Guid class
                    Guid tempCartId = Guid.NewGuid();
                    // Send tempCartId back to client as a cookie
                    context.Session[CartSessionKey] = tempCartId.ToString();
                }
            }
            return context.Session[CartSessionKey].ToString();
        }
        // When a user has logged in, migrate their shopping cart to
        // be associated with their username
        public void MigrateCart(string userName)
        {
            var shoppingCart = storeDB.Carts.Where(
                c => c.CartId == ShoppingCartId);
 
            foreach (Cart item in shoppingCart)
            {
                item.CartId = userName;
            }
            storeDB.SaveChanges();
        }
    }
}

Görünüm Modelleri

Alışveriş Sepeti Denetleyicimizin görünümlerine bazı karmaşık bilgiler iletmesi gerekir ve bu bilgiler Model nesnelerimizle düzgün bir şekilde eşlenmez. Modellerimizi görünümlerimize uyacak şekilde değiştirmek istemiyoruz; Model sınıfları, kullanıcı arabirimini değil etki alanımızı temsil etmelidir. Çözümlerden biri, Store Manager açılan bilgileriyle yaptığımız gibi ViewBag sınıfını kullanarak bilgileri Görünümlerimize geçirmek olabilir, ancak ViewBag aracılığıyla çok fazla bilgi geçirmek zorlaşır.

Bunun bir çözümü ViewModel desenini kullanmaktır. Bu düzeni kullanırken, belirli görünüm senaryolarımız için iyileştirilmiş ve görünüm şablonlarımız için gereken dinamik değerler/içerik için özellikleri kullanıma sunan kesin türe sahip sınıflar oluştururuz. Ardından denetleyici sınıflarımız bu görünüm için iyileştirilmiş sınıfları doldurabilir ve kullanmak üzere görünüm şablonumuza geçirebilir. Bu, görünüm şablonları içinde tür güvenliği, derleme zamanı denetimi ve düzenleyici IntelliSense'i etkinleştirir.

Alışveriş Sepeti denetleyicimizde kullanmak üzere iki Görünüm Modeli oluşturacağız: ShoppingCartViewModel kullanıcının alışveriş sepetinin içeriğini barındıracak ve kullanıcı sepetinden bir şey kaldırdığında onay bilgilerini görüntülemek için ShoppingCartRemoveViewModel kullanılacak.

Şimdi işleri düzenli tutmak için projemizin kökünde yeni bir ViewModels klasörü oluşturalım. Projeye sağ tıklayın, Ekle / Yeni Klasör'e tıklayın.

Sağ tıklama menüsünü gösteren ve Ekle ve Yeni Klasör seçeneklerinin sarı renkle vurgulandığı proje penceresinin ekran görüntüsü.

Klasörü ViewModels olarak adlandırın.

Yeni oluşturulan ve yeni adlandırılmış klasör olan Modelleri Görüntüle klasörünün siyah kutuyla vurgulandığı Çözüm Gezgini ekran görüntüsü.

Ardından, ViewModels klasörüne ShoppingCartViewModel sınıfını ekleyin. İki özelliği vardır: Sepet öğelerinin listesi ve sepetteki tüm öğelerin toplam fiyatını tutan ondalık değer.

using System.Collections.Generic;
using MvcMusicStore.Models;
 
namespace MvcMusicStore.ViewModels
{
    public class ShoppingCartViewModel
    {
        public List<Cart> CartItems { get; set; }
        public decimal CartTotal { get; set; }
    }
}

Şimdi Aşağıdaki dört özellik ile ShoppingCartRemoveViewModel'i ViewModels klasörüne ekleyin.

namespace MvcMusicStore.ViewModels
{
    public class ShoppingCartRemoveViewModel
    {
        public string Message { get; set; }
        public decimal CartTotal { get; set; }
        public int CartCount { get; set; }
        public int ItemCount { get; set; }
        public int DeleteId { get; set; }
    }
}

Alışveriş Sepeti Denetleyicisi

Alışveriş Sepeti denetleyicisinin üç ana amacı vardır: bir sepete ürün ekleme, sepetten öğeleri kaldırma ve sepetteki öğeleri görüntüleme. Yeni oluşturduğumuz üç sınıfı kullanacaktır: ShoppingCartViewModel, ShoppingCartRemoveViewModel ve ShoppingCart. StoreController ve StoreManagerController'da olduğu gibi, MusicStoreEntities örneğini barındıracak bir alan ekleyeceğiz.

Boş denetleyici şablonunu kullanarak projeye yeni bir Alışveriş Sepeti denetleyicisi ekleyin.

Denetleyici adı alanında Alışveriş Sepeti Denetleyicisi'nin mavi renkle vurgulandığı Denetleyici Ekle penceresinin ekran görüntüsü.

İşte tam ShoppingCart Controller. Dizin ve Denetleyici Ekle eylemleri çok tanıdık görünmelidir. Remove ve CartSummary denetleyici eylemleri, aşağıdaki bölümde ele alacağımız iki özel durumla ilgilenir.

using System.Linq;
using System.Web.Mvc;
using MvcMusicStore.Models;
using MvcMusicStore.ViewModels;
 
namespace MvcMusicStore.Controllers
{
    public class ShoppingCartController : Controller
    {
        MusicStoreEntities storeDB = new MusicStoreEntities();
        //
        // GET: /ShoppingCart/
        public ActionResult Index()
        {
            var cart = ShoppingCart.GetCart(this.HttpContext);
 
            // Set up our ViewModel
            var viewModel = new ShoppingCartViewModel
            {
                CartItems = cart.GetCartItems(),
                CartTotal = cart.GetTotal()
            };
            // Return the view
            return View(viewModel);
        }
        //
        // GET: /Store/AddToCart/5
        public ActionResult AddToCart(int id)
        {
            // Retrieve the album from the database
            var addedAlbum = storeDB.Albums
                .Single(album => album.AlbumId == id);
 
            // Add it to the shopping cart
            var cart = ShoppingCart.GetCart(this.HttpContext);
 
            cart.AddToCart(addedAlbum);
 
            // Go back to the main store page for more shopping
            return RedirectToAction("Index");
        }
        //
        // AJAX: /ShoppingCart/RemoveFromCart/5
        [HttpPost]
        public ActionResult RemoveFromCart(int id)
        {
            // Remove the item from the cart
            var cart = ShoppingCart.GetCart(this.HttpContext);
 
            // Get the name of the album to display confirmation
            string albumName = storeDB.Carts
                .Single(item => item.RecordId == id).Album.Title;
 
            // Remove from cart
            int itemCount = cart.RemoveFromCart(id);
 
            // Display the confirmation message
            var results = new ShoppingCartRemoveViewModel
            {
                Message = Server.HtmlEncode(albumName) +
                    " has been removed from your shopping cart.",
                CartTotal = cart.GetTotal(),
                CartCount = cart.GetCount(),
                ItemCount = itemCount,
                DeleteId = id
            };
            return Json(results);
        }
        //
        // GET: /ShoppingCart/CartSummary
        [ChildActionOnly]
        public ActionResult CartSummary()
        {
            var cart = ShoppingCart.GetCart(this.HttpContext);
 
            ViewData["CartCount"] = cart.GetCount();
            return PartialView("CartSummary");
        }
    }
}

JQuery ile Ajax Güncelleştirmeler

Bir sonraki adımda ShoppingCartViewModel'e kesin olarak yazılan ve daha önce olduğu gibi aynı yöntemi kullanarak Liste Görünümü şablonunu kullanan bir Alışveriş Sepeti Dizini sayfası oluşturacağız.

Görünüm adı alanını, Görünüm altyapısını, Model Sınıfını ve İskele açılan listelerini ve Düzen dosyası kullan seçicisini gösteren Görünüm Ekle penceresinin ekran görüntüsü.

Ancak, sepetten öğeleri kaldırmak için Html.ActionLink kullanmak yerine, bu görünümdeki HTML sınıfı RemoveLink'e sahip tüm bağlantılar için tıklama olayını "bağlamak" için jQuery kullanacağız. Bu tıklama olayı işleyicisi, formu göndermek yerine RemoveFromCart denetleyici eylemimize bir AJAX geri çağırması yapar. RemoveFromCart, jQuery geri çağırmamızın jQuery kullanarak ayrıştırdığı ve sayfada dört hızlı güncelleştirme gerçekleştirdiği JSON serileştirilmiş bir sonuç döndürür:

    1. Silinen albümü listeden kaldırır
    1. Üst bilgideki sepet sayısını Güncelleştirmeler
    1. Kullanıcıya bir güncelleştirme iletisi görüntüler
    1. Sepet toplam fiyatını Güncelleştirmeler

Kaldırma senaryosu Dizin görünümünde bir Ajax geri çağırması tarafından işlendiğinden RemoveFromCart eylemi için ek bir görünüme ihtiyacımız yoktur. /ShoppingCart/Index görünümünün tam kodu aşağıdadır:

@model MvcMusicStore.ViewModels.ShoppingCartViewModel
@{
    ViewBag.Title = "Shopping Cart";
}
<script src="/Scripts/jquery-1.4.4.min.js"
type="text/javascript"></script>
<script type="text/javascript">
    $(function () {
        // Document.ready -> link up remove event handler
        $(".RemoveLink").click(function () {
            // Get the id from the link
            var recordToDelete = $(this).attr("data-id");
            if (recordToDelete != '') {
                // Perform the ajax post
                $.post("/ShoppingCart/RemoveFromCart", {"id": recordToDelete },
                    function (data) {
                        // Successful requests get here
                        // Update the page elements
                        if (data.ItemCount == 0) {
                            $('#row-' + data.DeleteId).fadeOut('slow');
                        } else {
                            $('#item-count-' + data.DeleteId).text(data.ItemCount);
                        }
                        $('#cart-total').text(data.CartTotal);
                        $('#update-message').text(data.Message);
                        $('#cart-status').text('Cart (' + data.CartCount + ')');
                    });
            }
        });
    });
</script>
<h3>
    <em>Review</em> your cart:
 </h3>
<p class="button">
    @Html.ActionLink("Checkout
>>", "AddressAndPayment", "Checkout")
</p>
<div id="update-message">
</div>
<table>
    <tr>
        <th>
            Album Name
        </th>
        <th>
            Price (each)
        </th>
        <th>
            Quantity
        </th>
        <th></th>
    </tr>
    @foreach (var item in
Model.CartItems)
    {
        <tr id="row-@item.RecordId">
            <td>
                @Html.ActionLink(item.Album.Title,
"Details", "Store", new { id = item.AlbumId }, null)
            </td>
            <td>
                @item.Album.Price
            </td>
            <td id="item-count-@item.RecordId">
                @item.Count
            </td>
            <td>
                <a href="#" class="RemoveLink"
data-id="@item.RecordId">Remove
from cart</a>
            </td>
        </tr>
    }
    <tr>
        <td>
            Total
        </td>
        <td>
        </td>
        <td>
        </td>
        <td id="cart-total">
            @Model.CartTotal
        </td>
    </tr>
</table>

Bunu test etmek için alışveriş sepetimize ürün ekleyebilmemiz gerekiyor. Mağaza Ayrıntıları görünümümüzü bir "Sepete ekle" düğmesi içerecek şekilde güncelleştireceğiz. Bu aşamadayken, bu görünümü en son güncelleştirdiğimizden beri eklediğimiz Albüm ek bilgilerinden bazılarını ekleyebiliriz: Tarz, Sanatçı, Fiyat ve Albüm Resmi. Güncelleştirilmiş Mağaza Ayrıntıları görünüm kodu aşağıda gösterildiği gibi görünür.

@model MvcMusicStore.Models.Album
@{
    ViewBag.Title = "Album - " + Model.Title;
 }
<h2>@Model.Title</h2>
<p>
    <img alt="@Model.Title"
src="@Model.AlbumArtUrl" />
</p>
<div id="album-details">
    <p>
        <em>Genre:</em>
        @Model.Genre.Name
    </p>
    <p>
        <em>Artist:</em>
        @Model.Artist.Name
    </p>
    <p>
        <em>Price:</em>
        @String.Format("{0:F}",
Model.Price)
    </p>
    <p class="button">
        @Html.ActionLink("Add to
cart", "AddToCart", 
        "ShoppingCart", new { id = Model.AlbumId }, "")
    </p>
</div>

Şimdi mağazaya tıklayabilir ve alışveriş sepetimize albüm ekleme ve kaldırma test edebiliriz. Uygulamayı çalıştırın ve Mağaza Dizini'ne göz atın.

Veritabanına girilen tüm albüm verilerinden tanımlanan tarz ayrıntılarını gösteren Müzik Deposu penceresinin ekran görüntüsü.

Ardından, albüm listesini görüntülemek için bir Tarz'a tıklayın.

Albüm veritabanındaki Disko türüyle ilişkili albümlerin listesini gösteren Müzik Mağazası penceresinin ekran görüntüsü.

Bir Albüm başlığına tıkladığınızda artık "Sepete ekle" düğmesi de dahil olmak üzere güncelleştirilmiş Albüm Ayrıntıları görünümümüz gösterilir.

Güncelleştirilmiş Albüm Ayrıntıları görünümünü ve Sepete ekle düğmesini gösteren Müzik Mağazası penceresinin ekran görüntüsü.

"Sepete ekle" düğmesine tıklanması, alışveriş sepeti özet listesini içeren Alışveriş Sepeti Dizini görünümümüzü gösterir.

Alışveriş Sepeti görünümünü gösteren Ve sepetteki tüm öğelerin özet listesini gösteren Müzik Mağazası penceresinin ekran görüntüsü.

Alışveriş sepetinizi yükledikten sonra Alışveriş sepetinize yönelik Ajax güncelleştirmesini görmek için Sepetten kaldır bağlantısına tıklayabilirsiniz.

Albümün özet listesinden kaldırıldığı Alışveriş Sepeti görünümünü gösteren Müzik Mağazası penceresinin ekran görüntüsü.

Kayıtlı olmayan kullanıcıların sepetlerine ürün eklemesine olanak tanıyan çalışan bir alışveriş sepeti oluşturmuş olduk. Aşağıdaki bölümde, kaydolmalarına ve ödeme işlemini tamamlamalarına izin vereceğiz.