нокаут для каждого вложенного в с

Я хочу связать простую структуру с помощью ko, но во время привязки я получаю исключение. Моя виртуальная машина выглядит так:

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

Я пытаюсь перебрать все объекты в массиве records свойства longNameObjId1 и поместить их в таблицу. Мне действительно нужно иметь некоторый контроль над изменением массива записей, поэтому я начал с упаковки элемента управления потоком foreach, например:

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

Ничего фантастического. Что касается просмотра, я подумал, что это должно сработать:

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

Во время выполнения я вижу в браузере таблицу с ожидаемыми данными. Проблема, с которой я столкнулся, заключается в том, что я получаю исключение следующего вида:

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

Я бы с радостью проигнорировал ошибку, так как я вижу свои данные в браузере, но проблема заключается в том, что массив records на самом деле не привязан: например, вызов push () из консоли после отображения таблицы (и игнорирования ошибки) не запускает функцию dynCollection.update ().

Может кто-нибудь указать, где моя ошибка, или, возможно, лучший способ сопоставить массив records?

Я использую knockout 2.2.1 с FF 20.0 на Windows Server 2008 R2 SP1.

Если вам нужна дополнительная информация, дайте мне знать.
Спасибо,
Фло.

Обновление
Среди некоторых вещей, которые я пробовал, было использование свойства контекста $ data следующим образом:

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

Это оказалось довольно неожиданным поведением: ошибка больше не проявлялась, но и моя таблица не проявлялась: у меня на странице была пустая таблица, но ошибки не было. Должно быть что-то, чего я точно не понимаю в привязках. Буду признателен, если кто-нибудь сможет пролить свет на это конкретное поведение. Спасибо.


person Flo    schedule 26.04.2013    source источник
comment
dynCollection полностью избыточен, почему бы не использовать привязку foreach напрямую?   -  person Anders    schedule 26.04.2013
comment
Мне нужно улавливать все изменения в этой коллекции, независимо от того, является ли это действие пользователя или уведомление сервера, и выполнять дополнительные задачи на стороне клиента. Заключение привязки foreach было лишь первым шагом.   -  person Flo    schedule 29.04.2013
comment
Хорошо, только одна мысль, если только его логика и нет пользовательского интерфейса, он лучше подходит как наблюдаемый расширитель. пользовательские обработчики для ВМ ‹› привязок пользовательского интерфейса   -  person Anders    schedule 29.04.2013
comment
Спасибо за совет. Я проверю наблюдаемые расширители, так как у меня также будет много данных, которые войдут в d3.   -  person Flo    schedule 29.04.2013


Ответы (1)


Просто добавьте return перед своим foreach.init дополнительным вызовом:

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

Это останавливает создание шаблона строки таблицы, пока records не инициализирован.

person Rango    schedule 26.04.2013
comment
Чтобы уточнить, что это делает, это return {controlsDescendantBindings: true}, который заставит KO понять, что html, отображаемый привязкой, должен быть привязан не к текущему контексту, а к контексту, определенному обработчиком привязки. - person Anders; 26.04.2013