Як налагодити помилки прив'язки шаблону для KnockoutJS?


199

У мене постійно виникають проблеми з налагодженням шаблонів KnockoutJS.

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

Використання налагоджувача Chrome говорить лише мені:

"item" is not defined.

Чи є інструменти, методи чи стилі кодування, які допомагають мені отримати більше інформації про проблему зв’язування?

Відповіді:


344

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

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


ой. Мені теж потрібно поставити це питання. Використовується складний фрагмент коду для даних console.log. Зараз це набагато простіше.
AlfeG

3
Мені потрібно більше подумати про поради щодо налагодження і, можливо, зробити публікацію в блозі. Ще один, який спадає на думку, - це підписка вручну проти спостережуваних або обчислених спостережень, щоб спостерігати за зміною значень. Мовляв, якщо nameце спостерігається,name.subscribe(function(newValue) { console.log("name", newValue); });
Р. Німайєр

1
Це може бути тому, що ця відповідь відносно стара, але чому б не використовувати console.log і не використовувати всю потужність налагоджувача для перегляду властивостей об'єкта? Дивіться тобто: stackoverflow.com/a/16242988/647845
Дірк Бур

1
@DirkBoer - використання console.log також може бути чудовим способом. Дуже багато разів мені хочеться бачити дані поруч із своїми елементами, як у foreachсценарії, і мені стає легше бачити на сторінці у відповідній розміщеній розмітці, ніж просіювати консоль. Просто залежить від ситуації. Ще кілька моїх думок тут: knockmeout.net/2013/06/… . Крім того, ви можете увійти в "чисту" версію у своєму прив'язці, як console.log(ko.toJS(valueAccessor()).
RP Niemeyer

1
@RuneJeppesen - Я не впевнений, які саме дані ви серіалізуєте, але щось подібне може допомогти: knockmeout.net/2011/04/…
RP Niemeyer

61

Якщо ви використовуєте Chrome для розробки, є дійсно чудове розширення (з яким я не пов’язаний) під назвою контекстного налагоджувача Knockoutjs, яке показує вам контекст зв’язування безпосередньо на панелі "Елементи інструментів розробника".


3
Я б хотів, щоб у цього було Firefox або Firebug. Хтось знає про таке?
Патрік Шалапський

З'являється, підтримка відхилена. Причиняє збій хрому, якщо ви використовуєте складну структуру прив'язки даних. Вже майже рік не працює над жодним із моїх проектів.
Арктика

Вибачте, що це чую, хоча я давно перейшов з КО в Ембер.
neverfox

1
Для мене це працює (в основному) добре, і у мене є справді складні структури. Я не пробував цього, але в Параметрах для розширення він пропонує: "Якщо у вас трапляються збої, ви, мабуть, маєте не серіалізаційний режим перегляду. Ви можете вимкнути серіалізацію". Під повідомленням про відключення цієї функції є прапорець.
Грінн

надзвичайно корисно миттєво, ти.
Андрій

37

Визначте прив'язку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, лише для налагодження

введіть тут опис зображення


32

Я знайшов ще один, який може бути корисним. Я налагоджував деякі прив'язки і намагався використовувати приклад 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>

Дійсно корисна. Виникла кругова петля вибивання та проблеми розмітки Razor, використовуючи <pre data-bind = "text: ko.toJSON ($ data, null, 2)"> </pre>. <Попередній налагоджувач> - це ідеальне рішення. Чомусь входи RAZOR на кшталт @ Html.CheckBox зламали ko.toJSON.
Арктика

20

Покрокове керівництво

  1. Для цього посібника ми будемо використовувати один з офіційних прикладів KnockoutJS .
  2. Скажіть, ви хочете побачити дані за другим контактом (Sensei Miyagi).
  3. Клацніть правою кнопкою миші перше поле вводу другого контакту (того, з текстом "Sensei").
  4. Виберіть "Оглянути елемент". Відкриється панель інструментів для розробників Chrome.
  5. Відкрийте вікно консолі JavaScript. Ви можете отримати доступ до консолі, натиснувши >=піктограму в нижній лівій частині панелі інструментів для розробників Chrome або відкривши вкладку "Консоль" на панелі інструментів розробника Chrome, або натиснувши Ctrl+ Shift+J
  6. Введіть таку команду та натисніть Enter: ko.dataFor($0)
  7. Тепер ви повинні побачити дані, які пов'язані з другим рядом. Ви можете розгорнути дані, натиснувши на маленький трикутник зліва від Об’єкта для навігації по дереву об'єктів.
  8. Введіть таку команду та натисніть Enter: ko.contextFor($0)
  9. Тепер ви повинні побачити складний об'єкт, який містить весь контекст Knockout, включаючи корінь та всіх батьків. Це корисно, коли ви пишете складні виразні зв'язки та хочете експериментувати з різними конструкціями.

Приклад виведення при наступному вище керівництві

Що це за чорна магія?

Цей трюк - це поєднання функції Chrome від $ 0 до 4 та корисних методів KnockoutJS . Коротше кажучи, Chrome запам'ятовує , які елементи ви вибрали в Chrome Developer Toolbar і виставляє ці елементи під псевдонімом $0, $1, $2, $3, $4. Отже, коли ви клацніть правою кнопкою миші елемент у своєму браузері та виберіть "Оглянути елемент", цей елемент автоматично стає доступним під псевдонімом $0. Ви можете використовувати цей трюк за допомогою KnockoutJS, AngularJS, jQuery або будь-якого іншого фреймворку JavaScript.

Інша сторона хитрості - це корисні методи KnockoutJS ko.dataFor та ko.contextFor:

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

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

Щасливого налагодження!


7

Перевірте дійсно просту річ, яку я використовую:

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>

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

ОНОВЛЕННЯ

Ще одна дратівлива річ, коли ви намагаєтеся прив’язати до невизначеного значення. Уявіть у наведеному вище прикладі, що об’єктом даних є просто {} not {value: 'some text'}. У цьому випадку ви потрапите в біду, але з наступним виправленням у вас все буде добре:

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

5

Я створив проект github під назвою knockthrough.js, щоб допомогти візуалізувати ці помилки.

https://github.com/JonKragh/knockthrough

Він виділяє помилки прив'язки та дає дамп контексту даних на цьому вузлі.

Ви можете пограти зі зразком тут: http://htmlpreview.github.io/?https://github.com/JonKragh/knockthrough/blob/master/default.htm

введіть тут опис зображення

Подяка RP Niemeyer за його чудові зразки нокауту коду на SO, щоб довести мене до цього моменту.


3

Найпростіший спосіб зрозуміти, які дані передаються у прив'язку - це скинути дані на консоль:

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

Нокаут оцінить значення для прив'язки тексту ( будь-яке прив'язка тут може бути використане насправді ) та передає $ дані на консольну панель браузера.


2

Всі інші відповіді будуть чудово працювати, я просто додаю те, що мені подобається робити:

На ваш погляд (якщо припустити, що ви вже зв'язали ViewModel):

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

Код нокауту:

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

Це призупинить код у відладчику elementта valueAccessor()містить цінну інформацію.


немає необхідності у користувацькій прив'язці. Подивіться на stackoverflow.com/documentation/knockout.js/5066/…
Адам Вольський

1
Так, я згоден, немає певної необхідності робити це саме так, я просто хотів зазначити, що це один стиль налагодження ... всі, схоже, люблять робити це по-своєму :)
Aditya MP

1

Якщо ви розвиваєтеся в Visual studio і IE мені це більше data-bind="somebinding:(function(){debugger; return bindvalue; })()"подобається, це мені більше подобається, ніж функція echo, оскільки вона піде до сценарію з усіма прив’язками, а не файлом eval, і ви можете просто подивитися на $ контекст $ дані (я використовую це також у Chrome);


Надіваюся, це не має нічого спільного з Visual Studio або IE.
Сергій

@Serhiy Те саме з chrome, але в chrome Я думаю, ви могли отримати доступ до файлу без нього. Я не думаю, що ви можете отримати доступ до файлу в VS.
Філіп Кордас

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.