Question

I want to bind a simple structure with ko but I am getting an exception during binding. My VM looks like this:

function VM() {
    this["longNameObjId1"] = new Object();
    this["longNameObjId1"].records = ko.observableArray();

    var obj1 = new Object();
    obj1.L1 = "a";
    obj1.L2 = "b";
    obj1.L3 = "c";
    this["longNameObjId1"].records.push(obj1);

    var obj2 = new Object();
    obj2.L1 = "A";
    obj2.L2 = "B";
    obj2.L3 = "C";

    this["longNameObjId1"].records.push(obj2)            
}

I am trying to iterate through all the objects in the records array of the longNameObjId1 property and put them in a table. I do need to have some control over the changing of the records array, so I started with wrapping the foreach flow control, like this:

ko.bindingHandlers.dynCollection = {
    init: function (element, valueAccessor, allBindingsAccessor, viewModel, context){                
        ko.bindingHandlers.foreach.init(element, valueAccessor, allBindingsAccessor, viewModel, context);
    },
    update: function (element, valueAccessor, allBindingsAccessor, viewModel, context) {                
        ko.bindingHandlers.foreach.update(element, valueAccessor, allBindingsAccessor, viewModel, context);                
    }
};

Nothing fancy. On the view side, I thought this should do it:

<!-- ko with: longNameObjId1 -->
<table>
    <thead>
        <tr>
            <th style="width: 33%">L1</th>
            <th style="width: 25%">L2</th>
            <th style="width: 25%">L3</th>
            <th style="width: 17%"></th>
            <th></th>
        </tr>
    </thead>
    <tbody id="test_tBody" data-bind="dynCollection: records">
        <tr>
            <td id="test_td1" data-bind="text: L1"></td>
            <td id="test_td2" data-bind="text: L2"></td>
            <td id="test_td3" data-bind="text: L3"></td>
        </tr>
    </tbody>
</table>
<!-- /ko -->

At run time I can see the table in the browser, with the expected data. The problem that I am having is the fact that I receive an exception that goes like this:

Error: Unable to parse bindings.
Message: ReferenceError: L1 is not defined;
Bindings value: text: L1

I would happily ignore the error since I can see my data in the browser, but the problem is the fact that the records array is not really binded: for instance calling push() from the console after the table is displayed (and the error ignored) does not trigger the dynCollection.update() function.

Can somebody please point out where my error is, or perhaps a better way of mapping the records array?

I am using knockout 2.2.1 with FF 20.0 on a Windows Server 2008 R2 SP1.

If you need more details, please let me know.
Thanks,
Flo.

Update
Amongst some of the things that I tried was using the context property $data like this:

<td id="test_td1" data-bind="text: $data.L1"></td>

This turned out a rather unexpected behavior: the error no longer manifested itself, but nor did my table: I got an empty table in my page, but no error. There has to be something I definitely do not understand about bindings. I would appreciate if somebody can shed some light on this particular behavior. Thanks.

Was it helpful?

Solution

Just add return before your foreach.init subcall:

init: function (element, valueAccessor, allBindingsAccessor, viewModel, context){                
    return ko.bindingHandlers.foreach.init(element, valueAccessor, allBindingsAccessor, viewModel, context);
},

This stops table row templating while records is not initialized.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top