[英]My sample shopping cart is not working as expected knockout js
我正在学习knockout.js。 因此,我尝试构建一个样本购物车,最初会在其中附带产品数据。 当用户选择任何产品时,将在正确的输入控件中填写相应的价格和数量,并通过计算的属性自动计算小计。
最初,当我运行程序时,将显示一个购物车的数据,但是当我选择任何产品时,价格和数量值都不会被填满,也没有小计。 我是KO的新手,那为什么为什么我犯了一个愚蠢的错误,而这个错误却在我眼前变得不明显。 所以,请指导我哪里出错了。
<table id="table1" cellspacing="0" cellpadding="0" border="0">
<tr>
<th style="width:150px">Product</th>
<th>Price ($)</th>
<th>Quantity</th>
<th>Amount ($)</th>
</tr>
<tbody data-bind='template: {name: "orderTemplate", foreach: lines}'></tbody>
</table>
<script type="text/html" id="orderTemplate">
<tr>
<td><select data-bind="options: products,
optionsText: 'name',
value: id,
optionsCaption:'--Select--'">,
value: $parent.product
</select>
</td>
<td><span data-bind="value: price" /></td>
<td><input data-bind="value: quantity" /></td>
<td><span data-bind="value: subtotal" /></td>
</tr>
</script>
<script type="text/javascript">
var _products = [
{
"name": "1948 Porsche 356-A Roadster",
"price": 53.9
, quantity: 1
},
{
"name": "1948 Porsche Type 356 Roadster",
"price": 62.16
, quantity: 1
},
{
"name": "1949 Jaguar XK 120",
"price": 47.25
, quantity: 1
},
{
"name": "1952 Alpine Renault 1300",
"price": 98.58
, quantity: 1
},
{
"name": "1952 Citroen-15CV",
"price": 72.82
, quantity: 1
},
{
"name": "1956 Porsche 356A Coupe",
"price": 98.3
, quantity: 1
},
{
"name": "1957 Corvette Convertible",
"price": 69.93
, quantity: 1
}];
function formatCurrency(value) {
return "$" + value.toFixed(2);
}
var CartLine = function () {
var self = this;
self.products = ko.observableArray(_products);
self.product = ko.observable();
self.quantity = ko.observable(1);
self.price = ko.observable(1);
self.subtotal = ko.computed(function () {
return self.product() ? self.product().price * parseInt("0" + self.quantity(), 10) : 0;
});
};
var Cart = function () {
// Stores an array of lines, and from these, can work out the grandTotal
var self = this;
self.lines = ko.observableArray([new CartLine()]); // Put one line in by default
};
ko.applyBindings(new Cart());
</script>
所以这里有一些问题。 首先,您对下拉列表的绑定格式不正确
<select data-bind="options: products,
optionsText: 'name',
value: id,
optionsCaption:'--Select--'">,
value: $parent.product
</select>
值字段在数据绑定内声明为属性“ id”,而在视图模型中看不到该属性。 外部的值绑定('value:$ parent.product')绑定到有效的属性,但不在数据绑定内。 它看起来应该像这样:
<select data-bind="options: products,
optionsText: 'name',
value: product">
</select>
注意:我删除了optionsCaption,因为它只会用optionsCaption中的字符串覆盖您的“产品”对象(名称,价格和数量的对象)。 这会弄乱以后依赖“产品”对象属性的所有绑定。
至于您希望显示的其他字段:
<td><span data-bind="value: price" /></td>
<td><input data-bind="value: quantity" /></td>
<td><span data-bind="value: subtotal" /></td>
这些当前绑定到viewModel属性的价格,数量和小计。 它们都没有变化(并且跨度应绑定到“文本”而不是“值”)。 因此,我们需要将这些字段绑定到通过下拉菜单设置的对象,如下所示:
<td><span data-bind="text: product().price" /></td>
<td><input data-bind="value: product().quantity" /></td>
<td><span data-bind="text: product().total" /></td>
这将显示“价格”和“数量”的正确值。 但是,这些值不是可观察的,并且更改时不会更新任何计算结果。 因此,我们需要观察这些属性,以便通过在数量字段中键入并查看总更新来获得完整的响应感。 我更喜欢创建JS对象来保存这些可观察属性的集合:
function Product(data){
data = data || {};
var self = this;
self.name = ko.observable(data.name || "");
self.price = ko.observable(data.price || "0");
self.quantity = ko.observable(data.quantity || "0");
self.total = ko.computed(function(){
return self.price() * self.quantity();
});
}
为了保持一致性,我也将合计函数移到了该对象中。
要使用此功能,您可以通过传入具有适当属性的对象来调用它,也可以不进行任何调用而将其初始化为
{name: "", price: "0", quantity: "0"}.
这也意味着我们必须更改您的产品列表才能使用此新对象,否则该列表中的任何内容都不会具有可观察的属性。 您可以将'new Product()'包装在使用的现有JS对象周围:
var _products = [
new Product({
"name": "1948 Porsche 356-A Roadster",
"price": 53.9
, quantity: 1
}),
new Product({
"name": "1948 Porsche Type 356 Roadster",
"price": 62.16
, quantity: 1
}),
new Product({
"name": "1949 Jaguar XK 120",
"price": 47.25
, quantity: 1
}),
new Product({
"name": "1952 Alpine Renault 1300",
"price": 98.58
, quantity: 1
}),
new Product({
"name": "1952 Citroen-15CV",
"price": 72.82
, quantity: 1
}),
new Product({
"name": "1956 Porsche 356A Coupe",
"price": 98.3
, quantity: 1
}),
new Product({
"name": "1957 Corvette Convertible",
"price": 69.93
, quantity: 1
})];
您可以看到我在此提琴中提到的所有更改的全部内容: http : //jsfiddle.net/7e0vujf5/11/
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.