Wie debuggt man Vorlagenbindungsfehler für KnockoutJS?

Lesezeit: 7 Minuten

Benutzer-Avatar
Rogier Bessem

Ich habe immer wieder Probleme beim Debuggen von Problemen in KnockoutJS-Vorlagen.

Angenommen, ich möchte an eine Eigenschaft namens “binden”items” aber in der Vorlage mache ich einen Tippfehler und binde an die (nicht vorhandene) Eigenschaft “item“.

Die Verwendung des Chrome-Debuggers sagt mir nur:

"item" is not defined.

Gibt es Tools, Techniken oder Codierungsstile, die mir helfen, mehr Informationen über das Bindungsproblem zu erhalten?

Benutzer-Avatar
RP Niemeyer

Eine Sache, die ich ziemlich oft mache, wenn es ein Problem damit gibt, welche Daten in einem bestimmten Bereich verfügbar sind, ist, die Vorlage/den Abschnitt durch etwas wie das Folgende zu ersetzen:

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

Oder, wenn Sie eine etwas besser lesbare Version wünschen:

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

Dadurch werden die Daten ausgegeben, die in diesem Bereich gebunden werden, und Sie können sicherstellen, dass Sie die Dinge ordnungsgemäß verschachteln.

Update: ab KO 2.1können Sie es vereinfachen zu:

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

Nun werden die Argumente weitergegeben JSON.stringify.

  • ohh. Diese Frage muss ich auch mal stellen. Kompliziertes Stück Code für Daten in console.log verwendet. Jetzt ist es viel einfacher.

    – AlfeG

    13. Februar 2012 um 15:03 Uhr

  • Ich muss mehr über Debugging-Tipps nachdenken und vielleicht einen Blog-Beitrag machen. Eine andere, die mir in den Sinn kommt, ist die Durchführung manueller Abonnements für Observables oder berechnete Observables, um zu beobachten, wie sich Werte ändern. Wie wenn name ist ein beobachtbares Tun name.subscribe(function(newValue) { console.log("name", newValue); });

    – RP Niemeyer

    14. Februar 2012 um 14:55 Uhr


  • Könnte daran liegen, dass diese Antwort relativ alt ist, aber warum nicht console.log verwenden und die volle Leistung des Debuggers zum Anzeigen von Objekteigenschaften nutzen? Siehe zB: stackoverflow.com/a/16242988/647845

    – Dirk Boer

    25. März 2014 um 13:54 Uhr


  • @DirkBoer – Die Verwendung von console.log kann auch eine großartige Möglichkeit sein. Oft möchte ich die Daten neben meinen Elementen wie in a sehen foreach Szenario, und ich finde es einfacher, auf der Seite innerhalb des relevanten gerenderten Markups zu sehen, als die Konsole zu durchsuchen. Kommt eben auf die Situation an. Hier noch ein paar Gedanken von mir: knockmeout.net/2013/06/…. Außerdem möchten Sie vielleicht eine “saubere” Version in Ihrer Bindung protokollieren console.log(ko.toJS(valueAccessor()).

    – RP Niemeyer

    25. März 2014 um 18:26 Uhr

  • @RuneJeppesen – Ich bin mir nicht sicher, welche Art von Daten Sie serialisieren, aber so etwas kann helfen: knockmeout.net/2011/04/…

    – RP Niemeyer

    6. Mai 2014 um 13:16 Uhr

Wenn Sie Chrome für die Entwicklung verwenden, gibt es eine wirklich großartige Erweiterung (mit der ich nicht verbunden bin) namens Knockoutjs-Kontext-Debugger das zeigt Ihnen den Bindungskontext direkt im Bedienfeld „Elemente“ der Entwicklertools.

  • Ich wünschte, Firefox oder Firebug hätten das. Kennt jemand so etwas?

    – Patrick Szalapski

    2. Januar 2014 um 18:25 Uhr

  • Scheint, dass die Unterstützung eingestellt wurde. Verursacht einen Absturz von Chrome, wenn Sie eine komplexe Datenbindungsstruktur verwenden. Hat seit etwa einem Jahr für keines meiner Projekte mehr gearbeitet.

    – Arktis

    27. Januar 2015 um 19:59 Uhr

  • Tut mir leid, das zu hören, obwohl ich schon lange von KO zu Ember gewechselt bin.

    – Neverfox

    31. Januar 2015 um 21:57 Uhr

  • Es funktioniert (meistens) gut für mich, und ich habe einige wirklich komplexe Strukturen. Ich habe es nicht ausprobiert, aber in den Optionen für die Erweiterung wird vorgeschlagen: “Wenn Sie Abstürze erleben, haben Sie wahrscheinlich ein nicht serialisierbares Ansichtsmodell. Sie können die Serialisierung deaktivieren.” Unter der Nachricht befindet sich ein Kontrollkästchen zum Deaktivieren dieser Funktion.

    – Grins

    3. April 2015 um 18:53 Uhr

  • sofort enorm nützlich, ty.

    – Andreas

    3. März 2017 um 17:07 Uhr

Benutzer-Avatar
Dirk Boer

Definieren Sie einmal einen BindingHandlerirgendwo in Ihren JavaScript-Bibliotheksdateien.

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

als es einfach so zu verwenden:

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

Vorteile

  • Nutzen Sie die volle Leistung des Chrome-Debuggers, z Anzeige im Bedienfeld „Elemente“.
  • Sie müssen Ihrem DOM keine benutzerdefinierten Elemente hinzufügen, nur zum Debuggen

Geben Sie hier die Bildbeschreibung ein

Benutzer-Avatar
Rogier Bessem

Ich habe eine andere gefunden, die hilfreich sein kann. Ich habe einige Bindungen debuggt und versucht, Ryans Beispiel zu verwenden. Ich habe eine Fehlermeldung erhalten, dass JSON eine kreisförmige Schleife gefunden hat.

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

Bei diesem Ansatz wurde der Datenbindungswert jedoch durch Folgendes ersetzt:

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

Wenn ich jetzt auf das PRE-Element klicke, während das Chrome-Debug-Fenster geöffnet ist, erhalte ich ein gut gefülltes Bereichsvariablenfenster.

Habe einen etwas besseren Weg dafür gefunden:

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

Benutzer-Avatar
Martin Devillers

Schritt für Schritt Anleitung

  1. Für diese Anleitung verwenden wir eine der offizielle KnockoutJS-Beispiele.
  2. Angenommen, Sie möchten die Daten hinter dem zweiten Kontakt (Sensei Miyagi) sehen.
  3. Klicken Sie mit der rechten Maustaste auf das erste Eingabefeld des zweiten Kontakts (dasjenige mit dem Text „Sensei“).
  4. Wählen Sie „Element prüfen“. Die Chrome Developer Toolbar wird geöffnet.
  5. Öffnen Sie das JavaScript-Konsolenfenster. Sie können auf die Konsole zugreifen, indem Sie auf klicken >= Symbol unten links in der Chrome-Entwicklersymbolleiste oder durch Öffnen der Registerkarte „Konsole“ in der Chrome-Entwicklersymbolleiste oder durch Drücken von Strg+Wechsel+J
  6. Geben Sie den folgenden Befehl ein und drücken Sie die Eingabetaste: ko.dataFor($0)
  7. Sie sollten jetzt die Daten sehen, die an die zweite Zeile gebunden sind. Sie können die Daten erweitern, indem Sie auf das kleine Dreieck links neben dem Objekt drücken, um durch den Objektbaum zu navigieren.
  8. Geben Sie den folgenden Befehl ein und drücken Sie die Eingabetaste: ko.contextFor($0)
  9. Sie sollten jetzt ein komplexes Objekt sehen, das den gesamten Knockout-Kontext enthält, einschließlich des Stamms und aller Eltern. Dies ist nützlich, wenn Sie komplexe Bindungsausdrücke schreiben und mit verschiedenen Konstrukten experimentieren möchten.

Beispielausgabe bei Befolgung der obigen Anleitung

Was ist diese schwarze Magie?

Dieser Trick ist eine Kombination aus Die $0-$4-Funktion von Chrome und Die Utility-Methoden von KnockoutJS. Kurz gesagt, Chrome merkt sich, welche Elemente Sie in der Chrome Developer Toolbar ausgewählt haben, und zeigt diese Elemente unter dem Alias ​​an $0, $1, $2, $3, $4. Wenn Sie also in Ihrem Browser mit der rechten Maustaste auf ein Element klicken und „Element prüfen“ auswählen, wird dieses Element automatisch unter dem Alias ​​verfügbar $0. Sie können diesen Trick mit KnockoutJS, AngularJS, jQuery oder jedem anderen JavaScript-Framework verwenden.

Die andere Seite des Tricks sind die Hilfsmethoden ko.dataFor und ko.contextFor von KnockoutJS:

  • ko.dataFor(element) – gibt die Daten zurück, die für die Bindung an das Element verfügbar waren
  • ko.contextFor(element) – gibt den gesamten Bindungskontext zurück, der für das DOM-Element verfügbar war.

Denken Sie daran, dass die JavaScript-Konsole von Chrome eine voll funktionsfähige JavaScript-Laufzeitumgebung ist. Das bedeutet, dass Sie sich nicht nur auf Variablen beschränken müssen. Sie können die Ausgabe von speichern ko.contextFor und bearbeiten Sie das Ansichtsmodell direkt von der Konsole aus. Versuchen var root = ko.contextFor($0).$root; root.addContact(); und schau was passiert 🙂

Viel Spaß beim Debuggen!

Schauen Sie sich ein wirklich einfach Sache, die ich benutze:

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

Oder

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

Dann in HTML, sagen wir, Sie hatten:

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

Ersetzen Sie es einfach durch

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

Fortgeschrittener:

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

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

Genießen 🙂

AKTUALISIEREN

Eine weitere ärgerliche Sache ist, wenn Sie versuchen, an einen undefinierten Wert zu binden. Stellen Sie sich im obigen Beispiel vor, dass das Datenobjekt nur {} und nicht { value: ‘some text’ } ist. In diesem Fall werden Sie in Schwierigkeiten geraten, aber mit der folgenden Optimierung wird es Ihnen gut gehen:

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

Benutzer-Avatar
Jon Kragh

Ich habe ein Github-Projekt namens knockthrough.js erstellt, um diese Fehler zu visualisieren.

https://github.com/JonKragh/knockthrough

Es hebt Bindungsfehler hervor und gibt einen Dump des Datenkontexts auf diesem Knoten aus.

Hier können Sie mit einer Probe spielen: http://htmlpreview.github.io/?https://github.com/JonKragh/knockthrough/blob/master/default.htm

Geben Sie hier die Bildbeschreibung ein

Danke an RP Niemeyer für seine exzellenten Knockout-Codebeispiele auf SO, die mich an diesen Punkt gebracht haben.

1298330cookie-checkWie debuggt man Vorlagenbindungsfehler für KnockoutJS?

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy