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