Как отлаживать ошибки привязки шаблона для KnockoutJS?

У меня возникают проблемы с проблемами отладки в шаблонах KnockoutJS.

Скажем, я хочу привязываться к свойству с именем "items", но в шаблоне я делаю опечатку и привязываюсь к (не существующему) свойству "item".

Использование отладчика Chrome сообщает мне:

"item" is not defined.

Существуют ли инструменты, методы или стили кодирования, которые помогают мне получить дополнительную информацию о проблеме привязки?

Ответ 1

Одна вещь, которую я делаю довольно часто, когда есть проблема с тем, какие данные доступны в определенной области, заключается в замене шаблона/раздела чем-то вроде:

<div data-bind="text: ko.toJSON($data)"></div>

Или, если вы хотите немного более читаемую версию:

<pre data-bind="text: JSON.stringify(ko.toJS($data), null, 2)"></pre>

Это выплевывает данные, которые привязаны к этой области, и позволяю вам следить за тем, чтобы вы правильно вложили вещи.

Обновление: с KO 2.1 вы можете упростить его:

<pre data-bind="text: ko.toJSON($data, null, 2)"></pre>

Теперь аргументы передаются на JSON.stringify.

Ответ 2

Если вы используете Chrome для разработки, есть действительно отличное расширение (с которым я не являюсь аффилированным), называемый отладчиком контекста Knockoutjs, который показывает вам контекст привязки непосредственно на панели "Инструменты разработчика".

Ответ 3

Определить привязкуHandler один раз, где-то в ваших библиотечных файлах JavaScript.

ko.bindingHandlers.debug = 
{
    init: function(element, valueAccessor) 
    {
        console.log( 'Knockoutbinding:' );
        console.log( element );
        console.log( ko.toJS(valueAccessor()) );
    }
};

чем просто использовать это нравится:

<ul data-bind="debug: $data">

<сильные > Преимущества

  • Используйте всю мощь отладчика Chrome, например Reveal in Elements Panel
  • Вам не нужно добавлять пользовательские элементы в DOM, только для отладки

enter image description here

Ответ 4

Я нашел еще один, который может быть полезен. Я отлаживал некоторые привязки и пытался использовать пример Ryans. Я получил ошибку, что JSON нашел круговой цикл.

<ul class="list list-fix" data-bind="foreach: detailsView().tabs">
 <li>
   <pre data-bind="text: JSON.stringify(ko.toJS($parent), null, 2)"></pre>
   <a href="#" data-bind="click: $parent.setActiveTab, text: title"></a>
 </li>
</ul>

Но, используя этот подход, замените значение привязки данных следующим образом:

  <ul class="list list-fix" data-bind="foreach: detailsView().tabs">
    <li>
      <pre data-bind="text: 'click me', click: function() {debugger}"></pre>
      <a href="#" data-bind="click: $parent.setActiveTab, text: title"></a>
    </li>
  </ul>

Теперь, если я нажимаю на элемент PRE при открытии окна отладки хрома, я получаю красиво заполненное окно переменных области.

Нашел немного лучший способ:

<pre data-bind="text: ko.computed(function() { debugger; })"></pre>

Ответ 5

Пошаговое руководство

  • В этом руководстве мы будем использовать один из официальный KnockoutJS примеры.
  • Предположим, вы хотите видеть данные за вторым контактом (Sensei Мияги).
  • Щелкните правой кнопкой мыши по первому полю ввода второго контакта (с текст "Сенсей" ).
  • Выберите "Осмотреть элемент". Откроется панель инструментов разработчика Chrome.
  • Откройте окно консоли JavaScript. Вы можете получить доступ к консоли щелкнув значок >= в левом нижнем углу Chrome Developer Панель инструментов или открыв вкладку "Консоль" в Chrome Developer Панель инструментов или нажатием Ctrl + Shift + J
  • Введите следующую команду и нажмите Enter: ko.dataFor($0)
  • Теперь вы должны увидеть данные, привязанные ко второй строке. Ты можешь разверните данные, нажав маленький треугольник слева от объекта для перемещения по дереву объектов.
  • Введите следующую команду и нажмите Enter: ko.contextFor($0)
  • Теперь вы должны увидеть сложный объект, содержащий весь Контекст нокаута, включая корень и всех родителей. Это полезно когда вы пишете сложные выражения привязки, и вы хотите эксперимент с различными конструкциями.

Example output when following above guide

Что это за черная магия?

Этот трюк представляет собой комбинацию функция Chrome $0- $4 и KnockoutJS утилиты. Короче говоря, Chrome запоминает, какие элементы вы выбрали на панели инструментов разработчика Chrome, и предоставляет эти элементы под псевдонимами $0, $1, $2, $3, $4. Поэтому, когда вы щелкните правой кнопкой мыши элемент в своем браузере и выберите "Осмотреть элемент", этот элемент автоматически становится доступным под псевдонимом $0. Вы можете использовать этот трюк с KnockoutJS, AngularJS, jQuery или любой другой инфраструктурой JavaScript.

Другая сторона трюка - утилиты KnockoutJS ko.dataFor и ko.contextFor:

  • ko.dataFor(element) - возвращает данные, которые были доступны для привязки против элемента
  • ko.contextFor(element) - возвращает весь контекст привязки, который был доступный для элемента DOM.

Помните, что Chrome JavaScript Console - полностью функциональная среда выполнения JavaScript. Это означает, что вы не ограничены просто просмотром переменных. Вы можете сохранить вывод ko.contextFor и манипулировать viewmodel непосредственно с консоли. Попробуйте var root = ko.contextFor($0).$root; root.addContact(); и посмотрите, что произойдет: -)

Счастливая отладка!

Ответ 6

Проверьте действительно простую вещь, которую я использую:

function echo(whatever) { debugger; return whatever; }

Или

function echo(whatever) { console.log(whatever); return whatever; }

Тогда в html, скажем, вы имели:

<div data-bind="text: value"></div>

Просто замените его на

<div data-bind="text: echo(value)"></div>

Дополнительные возможности:

function echo(vars, member) { console.log(vars); debugger; return vars[0][member]; }

<div data-bind="text: echo([$data, $root, $parents, $parentContext], 'value')"></div>

Наслаждайтесь:)

UPDATE

Еще одна неприятная вещь - когда вы пытаетесь привязать к значению undefined. Представьте, что в приведенном выше примере объект данных просто {} not {значение: 'some text'}. В этом случае у вас будут проблемы, но со следующей настройкой вы будете в порядке:

<div data-bind="text: $data['value']"></div> 

Ответ 7

Я создал проект github под названием knockthrough.js, чтобы помочь визуализировать эти ошибки.

https://github.com/JonKragh/knockthrough

Он выделяет ошибки привязки и дает дамконтекст на этом node.

Вы можете играть с образцом здесь: http://htmlpreview.github.io/?https://github.com/JonKragh/knockthrough/blob/master/default.htm

enter image description here

Кредит RP Niemeyer за его отличные примеры кода нокаута на SO, чтобы довести меня до этого момента.

Ответ 8

Самый простой способ увидеть, какие данные передаются для привязки, - это удалить данные на консоль:

<div data-bind="text: console.log($data)"></div>

Нокаут будет оценивать значение для текстовой привязки (любая привязка может быть использована здесь фактически) и сбрасывает $data на панель консоли консоли.

Ответ 9

Если вы развиваетесь в Visual Studio и IE, мне больше нравится data-bind="somebinding:(function(){debugger; return bindvalue; })()" Мне больше нравится функция echo, так как она перейдет к script со всеми связями, а скорее с файлом eval, и вы можете просто взглянуть на $context $data (я использую это также в Chrome);

Ответ 10

Все остальные ответы будут работать отлично, я просто добавляю то, что мне нравится:

В вашем представлении (если вы уже связали ViewModel):

<div data-bind="debugger: $data"></div>

Код нокаута:

ko.bindingHandlers.debugger = {
    init: function (element, valueAccessor) {
        debugger;
    }
}

Это приведет к приостановке кода в отладчике, а element и valueAccessor() будет содержать ценную информацию.

Ответ 11

Это работает для меня:

<div data-bind="text: function(){ debugger; }()"></div>