KnockoutJS - 扩展购物车示例

时间:2012-08-27 00:33:47

标签: javascript json knockout.js

我目前正在尝试扩展KnockoutJS shopping cart example以从JSON集合中预加载现有行。

说,我有一个像这样的对象:

var existingRows = [{
        "Category":Classic Cars,
        "Product":2002 Chevy Corvette,
        "Quantity":1,
    }, {
        "Category":Ships,
        "Product":Pont Yacht,
        "Quantity":2,
}];

我正在尝试修改示例,以便在加载时使用两行填充网格,并将组合框预先设置为JSON对象中的项目。

我似乎无法使用JSFiddle很好地使用这个对象,但我已经修改了Cart和CartLine函数,并且ApplyBindings调用如下:

var CartLine = function(category, product) {
    var self = this;
    self.category = ko.observable(category);
    self.product = ko.observable(product);
    // other code
}

var Cart = function(data) {
    var self = this;
    self.lines = ko.observableArray(ko.utils.arrayMap(data, function(row) { return new CartLine(row.Category, row.Product);}))
    // other code
}

ko.applyBindings(new Cart(existingRows));

这会在加载时正确插入两行,但不会设置下拉列表。任何帮助将不胜感激:))

2 个答案:

答案 0 :(得分:4)

问题是CartLine对象中categoryproduct可观察对象的值不是简单字符串。它们是实际的物体,例如category是指该示例中提供的示例数据中的特定类别,与产品相同。 但你只是将它们设置为字符串。

(另一个问题是你的JS对象existingRows是无效的javascript,因为字符串周围缺少引号)

要使用您的existingRows对象获取该示例,您可以从示例数据中提取相关的类别和产品:

var Cart = function(data) {
    // Stores an array of lines, and from these, can work out the grandTotal
    var self = this;
    self.lines = ko.observableArray(ko.utils.arrayMap(data, function(row) {
        var rowCategory = ko.utils.arrayFirst(sampleProductCategories, function(category) {
            return category.name == row.Category;
        });
        var rowProduct = ko.utils.arrayFirst(rowCategory.products, function(product) {
            return product.name == row.Product;
        });

        return new CartLine(rowCategory, rowProduct, row.Quantity);
    }));
    // other code
}

更新了小提琴:http://jsfiddle.net/antishok/adNuR/664/

答案 1 :(得分:0)

<h1> Online shopping</h1>
<button id="btnAdd" data-bind='click: addLine'>Add product</button><br /><br />
<table width='100%'>
    <thead>
        <tr>
            <th width='25%'>Product</th>
            <th class='price' width='15%'>Price</th>
            <th class='quantity' width='10%'>Quantity</th>
            <th class='price' width='15%'>Subtotal (in rupees)</th>
            <th width='10%'> </th>
        </tr>
    </thead>
    <tbody data-bind='foreach: items'>
        <tr>
            <td>
                   <select data-bind='options: products, optionsText: "name", optionsCaption: "Select...", value: product'> </select>
            </td>
            <td class='price' data-bind='with: product'>
                <span data-bind='text: (price)'> </span>
            </td>
            <td class='quantity'>
                <input data-bind='visible:product, value: quantity, valueUpdate: "afterkeydown"' />
            </td>
            <td class='price'>
                <span data-bind='visible: product, text: subtotal()' > </span>
            </td>
            <td>
                <a href='#' data-bind='click: $parent.removeLine'>Remove</a>
            </td>
        </tr>
    </tbody>
</table>
<h2>
    Total value: <span data-bind='text: grandTotal()'></span> rupees
</h2>


$(document).ready(function () {
    $("#btnAdd").button();
    ko.applyBindings(new OnlineShopping());


});


function formatCurrency(value) {
    return "$" + value.toFixed(2);
}
var Item = function () {
    var self = this;
    self.product = ko.observable();
    self.quantity = ko.observable(1);
    self.subtotal = ko.computed(function () {
        var result = self.product() ? self.product().price * parseInt("0"+self.quantity(), 10) : 0;
        return result;
    });

};
var OnlineShopping = function () {
    var self = this;

    // List of items
    self.items = ko.observableArray([new Item()]);

    // Compute total prize. 
    self.grandTotal = ko.computed(function () {
        var total = 0;
        $.each(self.items(), function () { total += this.subtotal() })
        return total;
    });

    // Add item
    self.addLine = function () {
        self.items.push(new Item())
    };

    // Remove item
    self.removeLine = function () {
        self.items.remove(this)
    };
};

// Item collection
var products = [{ name: "IPhone", price: "45000" }, { name: "Galaxy Y", price: "7448" }, { name: "IPad", price: "25000" }, { name: "Laptop", price: "35000" }, { name: "Calci", price: "750"}];