Bölüm 7: Ana Sayfa Oluşturma
tarafından Rick Anderson
Ana Sayfayı Oluşturma
Bu bölümde ana uygulama sayfasını oluşturacaksınız. Bu sayfa Yönetici sayfadan daha karmaşık olacaktır, bu nedenle bu sayfaya birkaç adımda yaklaşacağız. Bu arada, daha gelişmiş Knockout.js tekniklerini göreceksiniz. Sayfanın temel düzeni aşağıdadır:
Ana sayfanın ürünler, sepet, siparişler ve sipariş ayrıntıları öğeleri arasındaki etkileşimin diyagramı. Products öğesi, items öğesine işaret eden bir okla GET A P I / products olarak etiketlenmiştir. Items öğesi orders öğesine POST A P I / orders etiketli bir okla bağlanır. orders öğesi GET A P I / orders etiketli bir okla details öğesine bağlanır. Details öğesi lebeled GET A P I / orders / i d.
- "Ürünler" bir dizi ürün içerir.
- "Sepet", miktarları olan bir ürün dizisini barındırıyor. "Sepete Ekle" seçeneğine tıklanması sepeti güncelleştirir.
- "Siparişler" bir dizi sipariş kimliği içerir.
- "Ayrıntılar" bir sipariş ayrıntısı içerir; bu bir dizi öğedir (miktarları olan ürünler)
Başlangıç olarak HTML'de veri bağlaması veya betik olmadan bazı temel düzenleri tanımlayacağız. Views/Home/Index.cshtml dosyasını açın ve tüm içeriği aşağıdakilerle değiştirin:
<div class="content">
<!-- List of products -->
<div class="float-left">
<h1>Products</h1>
<ul id="products">
</ul>
</div>
<!-- Cart -->
<div id="cart" class="float-right">
<h1>Your Cart</h1>
<table class="details ui-widget-content">
</table>
<input type="button" value="Create Order"/>
</div>
</div>
<div id="orders-area" class="content" >
<!-- List of orders -->
<div class="float-left">
<h1>Your Orders</h1>
<ul id="orders">
</ul>
</div>
<!-- Order Details -->
<div id="order-details" class="float-right">
<h2>Order #<span></span></h2>
<table class="details ui-widget-content">
</table>
<p>Total: <span></span></p>
</div>
</div>
Ardından, bir Betikler bölümü ekleyin ve boş bir görünüm modeli oluşturun:
@section Scripts {
<script type="text/javascript" src="@Url.Content("~/Scripts/knockout-2.1.0.js")"></script>
<script type="text/javascript">
function AppViewModel() {
var self = this;
self.loggedIn = @(Request.IsAuthenticated ? "true" : "false");
}
$(document).ready(function () {
ko.applyBindings(new AppViewModel());
});
</script>
}
Daha önce çizilen tasarıma göre, görünüm modelimizin ürünler, sepet, siparişler ve ayrıntılar için gözlemlenebilir öğelere ihtiyacı vardır. Nesnesine aşağıdaki değişkenleri AppViewModel
ekleyin:
self.products = ko.observableArray();
self.cart = ko.observableArray();
self.orders = ko.observableArray();
self.details = ko.observable();
Kullanıcılar ürünler listesindeki öğeleri sepete ekleyebilir ve sepetten öğe kaldırabilir. Bu işlevleri kapsüllemek için bir ürünü temsil eden başka bir görünüm modeli sınıfı oluşturacağız. Aşağıdaki kodu AppViewModel
dosyasına ekleyin:
function AppViewModel() {
// ...
// NEW CODE
function ProductViewModel(root, product) {
var self = this;
self.ProductId = product.Id;
self.Name = product.Name;
self.Price = product.Price;
self.Quantity = ko.observable(0);
self.addItemToCart = function () {
var qty = self.Quantity();
if (qty == 0) {
root.cart.push(self);
}
self.Quantity(qty + 1);
};
self.removeAllFromCart = function () {
self.Quantity(0);
root.cart.remove(self);
};
}
}
sınıfı, ProductViewModel
ürünü sepete taşımak ve sepetten taşımak için kullanılan iki işlev içerir: addItemToCart
ürünün bir birimini sepete ekler ve removeAllFromCart
ürünün tüm miktarlarını kaldırır.
Kullanıcılar mevcut bir siparişi seçebilir ve sipariş ayrıntılarını alabilir. Bu işlevi başka bir görünüm modeline kapsülleyeceğiz:
function AppViewModel() {
// ...
// NEW CODE
function OrderDetailsViewModel(order) {
var self = this;
self.items = ko.observableArray();
self.Id = order.Id;
self.total = ko.computed(function () {
var sum = 0;
$.each(self.items(), function (index, item) {
sum += item.Price * item.Quantity;
});
return '$' + sum.toFixed(2);
});
$.getJSON("/api/orders/" + order.Id, function (order) {
$.each(order.Details, function (index, item) {
self.items.push(item);
})
});
};
}
OrderDetailsViewModel
bir siparişle başlatılır ve sunucuya bir AJAX isteği göndererek sipariş ayrıntılarını getirir.
Ayrıca üzerindeki özelliğine total
OrderDetailsViewModel
de dikkat edin. Bu özellik, hesaplanan gözlemlenebilir olarak adlandırılan özel bir gözlemlenebilir türüdür. Adından da anlaşılacağı gibi, hesaplanan gözlemlenebilir veriler hesaplanan bir değere (bu örnekte siparişin toplam maliyeti) bağlanmanızı sağlar.
Ardından, bu işlevleri öğesine AppViewModel
ekleyin:
resetCart
sepetten tüm öğeleri kaldırır.getDetails
siparişin ayrıntılarını alır (listeye yeniOrderDetailsViewModel
details
bir sipariş göndererek).createOrder
yeni bir sipariş oluşturur ve sepeti boşalttır.
function AppViewModel() {
// ...
// NEW CODE
self.resetCart = function() {
var items = self.cart.removeAll();
$.each(items, function (index, product) {
product.Quantity(0);
});
}
self.getDetails = function (order) {
self.details(new OrderDetailsViewModel(order));
}
self.createOrder = function () {
var jqxhr = $.ajax({
type: 'POST',
url: "api/orders",
contentType: 'application/json; charset=utf-8',
data: ko.toJSON({ Details: self.cart }),
dataType: "json",
success: function (newOrder) {
self.resetCart();
self.orders.push(newOrder);
},
error: function (jqXHR, textStatus, errorThrown) {
self.errorMessage(errorThrown);
}
});
};
};
Son olarak, ürünler ve siparişler için AJAX istekleri yaparak görünüm modelini başlatın:
function AppViewModel() {
// ...
// NEW CODE
// Initialize the view-model.
$.getJSON("/api/products", function (products) {
$.each(products, function (index, product) {
self.products.push(new ProductViewModel(self, product));
})
});
$.getJSON("api/orders", self.orders);
};
Pekâlâ, bu çok fazla kod ama bunu adım adım oluşturduğumuz için tasarımın net olduğunu umuyoruz. Artık HTML'ye bazı Knockout.js bağlamaları ekleyebiliriz.
Ürünler
Ürün listesinin bağlamaları şunlardır:
<ul id="products" data-bind="foreach: products">
<li>
<div>
<span data-bind="text: Name"></span>
<span class="price" data-bind="text: '$' + Price"></span>
</div>
<div data-bind="if: $parent.loggedIn">
<button data-bind="click: addItemToCart">Add to Order</button>
</div>
</li>
</ul>
Bu, products dizisini yineler ve adı ve fiyatı görüntüler. "Siparişe Ekle" düğmesi yalnızca kullanıcı oturum açtığında görünür.
"Siparişe Ekle" düğmesi, ürünün örneğini ProductViewModel
çağırıraddItemToCart
. Bu, Knockout.js güzel bir özelliğini gösterir: Görünüm modeli başka görünüm modelleri içeriyorsa, bağlamaları iç modele uygulayabilirsiniz. Bu örnekte içindeki bağlamalar foreach
örneklerin ProductViewModel
her birine uygulanır. Bu yaklaşım, tüm işlevleri tek bir görünüm modeline yerleştirmekten çok daha temizdir.
Sepet
Sepet için bağlamalar şunlardır:
<div id="cart" class="float-right" data-bind="visible: cart().length > 0">
<h1>Your Cart</h1>
<table class="details ui-widget-content">
<thead>
<tr><td>Item</td><td>Price</td><td>Quantity</td><td></td></tr>
</thead>
<tbody data-bind="foreach: cart">
<tr>
<td><span data-bind="text: $data.Name"></span></td>
<td>$<span data-bind="text: $data.Price"></span></td>
<td class="qty"><span data-bind="text: $data.Quantity()"></span></td>
<td><a href="#" data-bind="click: removeAllFromCart">Remove</a></td>
</tr>
</tbody>
</table>
<input type="button" data-bind="click: createOrder" value="Create Order"/>
Bu, sepet dizisi üzerinde yinelenir ve adı, fiyatı ve miktarı görüntüler. "Kaldır" bağlantısının ve "Sipariş Oluştur" düğmesinin görünüm modeli işlevlerine bağlı olduğunu unutmayın.
Siparişler
Sipariş listesinin bağlamaları şunlardır:
<h1>Your Orders</h1>
<ul id="orders" data-bind="foreach: orders">
<li class="ui-widget-content">
<a href="#" data-bind="click: $root.getDetails">
Order # <span data-bind="text: $data.Id"></span></a>
</li>
</ul>
Bu, siparişler üzerinde yinelenir ve sipariş kimliğini gösterir. Bağlantıdaki tıklama olayı işleve getDetails
bağlıdır.
Sipariş Ayrıntıları
Sipariş ayrıntıları için bağlamalar şunlardır:
<div id="order-details" class="float-right" data-bind="if: details()">
<h2>Order #<span data-bind="text: details().Id"></span></h2>
<table class="details ui-widget-content">
<thead>
<tr><td>Item</td><td>Price</td><td>Quantity</td><td>Subtotal</td></tr>
</thead>
<tbody data-bind="foreach: details().items">
<tr>
<td><span data-bind="text: $data.Product"></span></td>
<td><span data-bind="text: $data.Price"></span></td>
<td><span data-bind="text: $data.Quantity"></span></td>
<td>
<span data-bind="text: ($data.Price * $data.Quantity).toFixed(2)"></span>
</td>
</tr>
</tbody>
</table>
<p>Total: <span data-bind="text: details().total"></span></p>
</div>
Bu, siparişteki öğeleri yineler ve ürünü, fiyatı ve miktarı görüntüler. Çevresindeki div yalnızca details dizisinde bir veya daha fazla öğe varsa görünür.
Sonuç
Bu öğreticide veritabanıyla iletişim kurmak için Entity Framework kullanan bir uygulama oluşturdunuz ve veri katmanının üstünde genel kullanıma yönelik bir arabirim sağlamak için Web API'sini ASP.NET. HTML sayfalarını işlemek için ASP.NET MVC 4 ve sayfa yeniden yüklemeleri olmadan dinamik etkileşimler sağlamak için Knockout.js artı jQuery kullanıyoruz.
Ek kaynaklar: