Javascript 结合两个淘汰的例子

Javascript 结合两个淘汰的例子,javascript,knockout.js,Javascript,Knockout.js,我正试图从knockout.com上找到两个例子,但我还没有弄清楚。任何帮助都将不胜感激 运行此项目并使用调试器时,我收到一个错误: 未捕获引用错误:无法处理绑定foreach:function{return linesa} 消息:未定义linesa 从最初的示例中,我将lines更改为linesa,以查看是否有其他内容将其搞糟。它仍然不喜欢琳萨 我的主要目标是让这两个样本一起工作。“添加联系人”按钮起作用,但“添加产品”不起作用 谢谢大家! <div class='liveExa

我正试图从knockout.com上找到两个例子,但我还没有弄清楚。任何帮助都将不胜感激

运行此项目并使用调试器时,我收到一个错误: 未捕获引用错误:无法处理绑定foreach:function{return linesa} 消息:未定义linesa

从最初的示例中,我将lines更改为linesa,以查看是否有其他内容将其搞糟。它仍然不喜欢琳萨

我的主要目标是让这两个样本一起工作。“添加联系人”按钮起作用,但“添加产品”不起作用

谢谢大家!

    <div class='liveExample'> 

    <h2>Contacts</h2>
    <div id='contactsList'>
        <table class='contactsEditor'>
            <tr>
                <th>First name</th>
                <th>Last name</th>
                <th>Phone numbers</th>
            </tr>
            <tbody data-bind="foreach: contactsa">
                <tr>
                    <td>
                        <input data-bind='value: firstName' />
                        <div><a href='#' data-bind='click: $root.removeContact'>Delete</a></div>
                    </td>
                    <td><input data-bind='value: lastName' /></td>
                    <td>
                        <table>
                            <tbody data-bind="foreach: phones">
                                <tr>
                                    <td><input data-bind='value: type' /></td>
                                    <td><input data-bind='value: number' /></td>
                                    <td><a href='#' data-bind='click: $root.removePhone'>Delete</a></td>
                                </tr>
                            </tbody>
                        </table>
                        <a href='#' data-bind='click: $root.addPhone'>Add number</a>
                    </td>
                </tr>
            </tbody>
        </table>
    </div>

    <p>
        <button data-bind='click: addContact'>Add a contact</button>
        <button data-bind='click: save, enable: contactsa().length > 0'>Save to JSON</button>
    </p>

    <textarea data-bind='value: lastSavedJson' rows='5' cols='60' disabled='disabled'> </textarea>

</div>

<div class='liveExample'> 

    <table width='100%'>
        <thead>
            <tr>
                <th width='25%'>Category</th>
                <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</th>
                <th width='10%'> </th>
            </tr>
        </thead>
        <tbody data-bind='foreach: linesa'>
            <tr>
                <td>
                    <select data-bind='options: sampleProductCategories, optionsText: "name", optionsCaption: "Select...", value: category'> </select>
                </td>
                <td data-bind="with: category">
                    <select data-bind='options: products, optionsText: "name", optionsCaption: "Select...", value: $parent.product'> </select>
                </td>
                <td class='price' data-bind='with: product'>
                    <span data-bind='text: formatCurrency(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: formatCurrency(subtotal())' > </span>
                </td>
                <td>
                    <a href='#' data-bind='click: $parent.removeLine'>Remove</a>
                </td>
            </tr>
        </tbody>
    </table>
    <p class='grandTotal'>
        Total value: <span data-bind='text: formatCurrency(grandTotal())'> </span>
    </p>
    <button data-bind='click: addLine'>Add product</button>
    <button data-bind='click: save'>Submit order</button>

</div>

    var initialData = [
    { firstName: "Danny", lastName: "LaRusso", phones: [
        { type: "Mobile", number: "(555) 121-2121" },
        { type: "Home", number: "(555) 123-4567"}]
    },
    { firstName: "Sensei", lastName: "Miyagi", phones: [
        { type: "Mobile", number: "(555) 444-2222" },
        { type: "Home", number: "(555) 999-1212"}]
    }
];

var ContactsModel = function(contactstest) {
    var self = this;
    self.contactsa = ko.observableArray(ko.utils.arrayMap(contactstest, function(contact) {
        return { firstName: contact.firstName, lastName: contact.lastName, phones: ko.observableArray(contact.phones) };
    }));

    self.addContact = function() {
        self.contactsa.push({
            firstName: "",
            lastName: "",
            phones: ko.observableArray()
        });
    };

    self.removeContact = function(contact) {
        self.contactsa.remove(contact);
    };

    self.addPhone = function(contact) {
        contact.phones.push({
            type: "",
            number: ""
        });
    };

    self.removePhone = function(phone) {
        $.each(self.contactsa(), function() { this.phones.remove(phone) })
    };

    self.save = function() {
        self.lastSavedJson(JSON.stringify(ko.toJS(self.contactsa), null, 2));
    };

    self.lastSavedJson = ko.observable("")
};

ko.applyBindings(new ContactsModel(initialData));

function formatCurrency(value) {
    return "$" + value.toFixed(2);
}

var CartLine = function() {
    var self = this;
    self.category = ko.observable();
    self.product = ko.observable();
    self.quantity = ko.observable(1);
    self.subtotal = ko.computed(function() {
        return self.product() ? self.product().price * parseInt("0" + self.quantity(), 10) : 0;
    });

    // Whenever the category changes, reset the product selection
    self.category.subscribe(function() {
        self.product(undefined);
    });
};

var Cart = function() {
    // Stores an array of lines, and from these, can work out the grandTotal
    var self = this;
    self.linesa = ko.observableArray([new CartLine()]); // Put one line in by default
    self.grandTotal = ko.computed(function() {
        var total = 0;
        $.each(self.linesa(), function() { total += this.subtotal() })
        return total;
    });

    // Operations
    self.addLine = function() { self.linesa.push(new CartLine()) };
    self.removeLine = function(line) { self.linesa.remove(line) };
    self.save = function() {
        var dataToSave = $.map(self.linesa(), function(line) {
            return line.product() ? {
                productName: line.product().name,
                quantity: line.quantity()
            } : undefined
        });
        alert("Could now send this to server: " + JSON.stringify(dataToSave));
    };
};

ko.applyBindings(new Cart());

ViewModel是一个ContactsModel,因为ContactsModel没有linesa属性,所以它无法呈现表的内容

<tbody data-bind='foreach: linesa'>
以及绑定

<div data-bind="with:cart"><!-- cart html view goes here --></div>
<div data-bind="with:contact"><!-- contact html view goes here --></div>

如果我把这两个例子分成不同的例子,它们都很好用。非常感谢!这完全有道理!以下是完整的解决方案,以防其他人发现它有帮助。下面是一个更新的示例,其中数字起作用。
<div data-bind="with:cart"><!-- cart html view goes here --></div>
<div data-bind="with:contact"><!-- contact html view goes here --></div>