Thomas
Thomas

Reputation: 34188

When to use different approaches for data binding?

Here I have two JSFiddle links; the code in both links is doing the same thing, more or less, but their data binding approach is different.

1) First JSFiddle link: if anyone looks at the code from this fiddle, they'll notice how they bind data:

<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>    

Qty and price properties, etc., are not the property of line collection, because the outer loop iterates in line collection. So how do Qty, price, and product understand the mapping between the data source and property?

2) Second JSFiddle link:

<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>

Here, price, qty, etc., refer to the product before, like text: product().price, but first the binding does not refer to anything like data-bind='value:quantity'.

Why do two people use two different data-binding approaches? When do we need to refer to something like product() first and then property name? Why does the first binding not require referencing anything?

Upvotes: 0

Views: 67

Answers (1)

TSV
TSV

Reputation: 7641

Using

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

is a dangerous approach. If product() is undefined, you will get a null reference exception when processing this binding.

Also, ko if binding does not render content at all if condition is wrong (your table will be rendered without two cells in this case), so if internals of the ko if binding are rather "heavy" - this construction can take more time to update.

I think it will be a bit better to use with binding after ko if (it looks strange for me that original code works):

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

UPDATE 1

Sorry, I've focused on the markup first. If we take a look on your model (and now I understood why product().quantity does not fail with an exception), the each line of lines is a CartLine object:

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);

};

the

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

binding uses the quantity property of the CartLine object

but the

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

binding uses the product().quantity property of the CartLine object. This is completely different property of another (Product, not CartLine) object.

I'm not sure I've understood your model right, but it seems to me, that CartLine's quantity value (amount of good customer are going to buy) is a different thing than Product quantity value (amount of good available in store).

Upvotes: 2

Related Questions