0

我正在尝试将文本框中的值提交到一个数组中,该数组将以表格格式显示。将进行进一步的计算,但现在我遇到了绑定问题。在 chrome 的控制台中,我得到的错误是

Uncaught TypeError: Property 'item' of object#<ItemEntry> is not a function

我不知道应该在哪里定义 newItem (从文本框提交的值)。

这是HTML

<td><input type="text" data-bind="value: newItem" /></td>
<button data-bind="click: addItem">Add Item</button>

<table>
    <thead><tr>
        <th>Item Number</th><th>Price</th><th></th>
    </tr></thead>
    <tbody data-bind="foreach: itemNumbers">
        <tr>
            <td data-bind="text: item"></td>
            <td data-bind="text: price"></td>
            <td><a href="#" data-bind="click: $root.removeItem">Remove</a></td>
        </tr>    
    </tbody>
</table>

<h3 data-bind="visible: totalCost() > 0">
    Total Cost: $<span data-bind="text: totalCost().toFixed(2)"></span>
</h3>

这是javascript

function ItemEntry(item, price) {
    var self = this;
    self.item = item;
    self.price = price;

}

// Overall viewmodel for this screen, along with initial state
function EntryViewModel(newItem) {
    var self = this;
    self.newItem = newItem;


    // Editable data
    self.itemNumbers = ko.observableArray([
        new ItemEntry("New Item", "$22.50")
    ]);

    // Computed data
    self.totalCost = ko.computed(function() {
       var total = 0;
       for (var i = 0; i < self.itemNumbers().length; i++)
           total += self.itemNumbers()[i].item.price;
       return total;
    });    

    // Operations
    self.addItem = function() {
        self.itemNumbers.push(new ItemEntry(self.newItem, "$20.00"));
    }
    self.removeItem = function(item) { self.itemNumbers.remove(item) }
}

ko.applyBindings(new EntryViewModel());
4

1 回答 1

1

我看到了一些您可能想要进行的更新:

  • ItemEntry 接受一个Price参数,而您price在构造函数中处理
  • 您的商品/价格在 ItemEntry 中不是可观察的,因此您formattedPrice不需要计算,它可以只是一个普通函数(除非您选择使它们可观察,就像您制作了一个完整的编辑器一样
  • formattedPrice函数正在尝试读取item.price(). 价格是一个单独的参数,item实际上只是项目的名称。
  • formattedPrice您可能需要考虑将值解析为数字
  • 当您调用addItem第一个参数时,将是该上下文中的数据(即根视图模型)。因此,您可以阅读newItem它,也可以仅使用self.newItem()您当前的结构。
  • 在结束时addItem,您可能想要清除newItem,因此输入框已准备好进行下一个条目。
  • 您的totalCost计算正在阅读item().price,只需要做item.price.

这是一个包含许多这些变化的更新小提琴:http: //jsfiddle.net/rniemeyer/8cDUn/

如果您想为这些项目创建一个编辑器,那么您可能希望使ItemEntry成员可观察。

于 2013-04-05T13:13:53.197 回答