Как отлаживать ошибки привязки шаблона для 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>