何时使用不同的数据绑定方法?

时间:2015-06-03 13:45:02

标签: knockout.js

这里我有两个JSFiddle链接;两个链接中的代码或多或少地做同样的事情,但它们的数据绑定方法是不同的。

1)第一个JSFiddle链接: 如果有人看到这个小提琴的代码,他们会注意到他们如何绑定数据:

<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",
                               optionsCaption:"--Select--",
                               value: product'>
                               </select>
        </td>
        <!-- ko if:product -->
        <td>
            <span data-bind='text:price' ></span>
        </td>
        <td>
            <input data-bind='value:quantity' />
        </td>
           <!--/ko-->
        <td ><span data-bind='text:formatCurrency(subtotal())'></span></td>

    </tr> 
</script>    

数量和价格属性等不是行集合的属性,因为外部循环在行集合中迭代。那么数量,价格和产品如何理解数据源和属性之间的映射呢?

2)第二个JSFiddle链接:

<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: product">
                               </select>
        </td>
        <td><span data-bind="text: product().price" /></td>
        <td><input data-bind="value: product().quantity" /></td>
        <td><span data-bind="text: product().total" /></td>
    </tr>
</script>

这里,price,qty等是指之前的产品,如text: product().price,但首先绑定不是指data-bind='value:quantity'之类的东西。

为什么两个人使用两种不同的数据绑定方法?我们什么时候需要首先引用product()之类的东西然后再引用属性名称?为什么第一个绑定不需要引用任何东西?

1 个答案:

答案 0 :(得分:2)

使用

data-bind="text: product().price"

是一种危险的方法。如果未定义product(),则在处理此绑定时将获得空引用异常。

此外,如果条件错误,ko if绑定根本不呈现内容(在这种情况下,您的表将呈现为没有两个单元格),因此如果ko if绑定的内部相当“重” “ - 这种结构可能需要更多时间来更新。

我认为在with之后使用ko if绑定会更好一点(对我来说原始代码看起来很奇怪):

<!-- ko if:product -->
    <!-- ko with:product -->
        <td>
            <span data-bind='text:price' ></span>
        </td>
        <td>
            <input data-bind='value:quantity' />
        </td>
    <!--/ko-->
<!--/ko-->

更新1

抱歉,我首先关注的是标记。如果我们看一下您的模型(现在我理解为什么product().quantity不会因异常而失败),lines的每一行都是CartLine对象:

var CartLine = function () {
    var self = this;
    self.products = ko.observableArray(_products);
    self.product = ko.observable(1);
    self.quantity = ko.observable(1);
    self.price = ko.observable(1);

};

  <input data-bind='value:quantity' />

绑定使用CartLine对象的quantity属性

但是

  <input data-bind="value: product().quantity" />

绑定使用CartLine对象的product().quantity属性。这是另一个(产品,而不是CartLine)对象的完全不同的属性。

我不确定我是否理解你的模型,但在我看来,CartLine的quantity价值(优质顾客的数量将会购买)与产品{{1}不同} value(商店中可用的商品数量)。