web-dev-qa-db-ja.com

KnockoutJSのテンプレートバインディングエラーをデバッグする方法は?

KnockoutJSテンプレートの問題のデバッグに引き続き問題があります。

items」というプロパティにバインドしたいが、テンプレートではタイプミスを行い、(存在しない)プロパティ「item」にバインドするとします。

Chromeデバッガーを使用すると、次のことしかわかりません。

"item" is not defined.

バインディングの問題に関する詳細情報を入手するのに役立つツール、テクニック、またはコーディングスタイルはありますか?

198
RogierBessem

特定のスコープで使用可能なデータに問題がある場合に頻繁に行うことの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に渡されます。

340
RP Niemeyer

開発にChromeを使用している場合、開発者に直接バインディングコンテキストを表示する Knockoutjsコンテキストデバッガー と呼ばれる非常に優れた拡張機能があります(私は提携していません)。ツールの要素パネル。

60
neverfox

bindingHandlerを1回定義、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デバッガーの全機能を使用するElements Panelで公開する
  • デバッグのためだけに、DOMにカスタム要素を追加する必要はありません。

enter image description here

36
Dirk Boer

私は役に立つことができる別のものを見つけました。私はいくつかのバインディングをデバッグしていて、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>

chromeデバッグウィンドウを開いた状態でPRE要素をクリックすると、スコープ変数ウィンドウがきれいに表示されます。

それのための少し良い方法を見つけました:

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

ステップバイステップガイド

  1. このガイドでは、 公式KnockoutJSの例 のいずれかを使用します。
  2. 2番目の連絡先(宮城先生)の背後にあるデータを表示するとします。
  3. 2番目の連絡先(「Sensei」というテキストのある連絡先)の最初の入力ボックスを右クリックします。
  4. 「要素の検査」を選択します。 Chrome Developerツールバーが開きます。
  5. JavaScriptコンソールウィンドウを開きます。コンソールにアクセスするには、Chrome Developerツールバーの左下にある>=アイコンをクリックするか、Chrome Developerツールバーの[コンソール]タブを開くか、を押します。 Ctrl+Shift+J
  6. 次のコマンドを入力して、Enterキーを押します。ko.dataFor($0)
  7. これで、2行目にバインドされたデータが表示されます。オブジェクトの左にある小さな三角形を押してオブジェクトツリーをナビゲートすると、データを展開できます。
  8. 次のコマンドを入力して、Enterキーを押します。ko.contextFor($0)
  9. ルートとすべての親を含むKnockoutコンテキスト全体を含む複雑なオブジェクトが表示されます。これは、複雑なバインディング式を作成していて、さまざまな構成を試してみたい場合に便利です。

Example output when following above guide

この黒魔術とは何ですか?

このトリックは、 Chromeの$ 0- $ 4機能KnockoutJSのユーティリティメソッド の組み合わせです。つまり、Chromeは、Chrome Developerツールバーで選択した要素を記憶し、これらの要素をエイリアス$0$1$2$3$4で公開します。そのため、ブラウザで要素を右クリックして「要素の検査」を選択すると、この要素はエイリアス$0で自動的に使用可能になります。このトリックは、KnockoutJS、AngularJS、jQuery、またはその他のJavaScriptフレームワークで使用できます。

トリックのもう1つの側面は、KnockoutJSのユーティリティメソッドko.dataForおよびko.contextForです。

  • ko.dataFor(element)-要素に対するバインディングに利用可能なデータを返します
  • ko.contextFor(element)-DOM要素で利用可能なバインディングコンテキスト全体を返します。

ChromeのJavaScriptコンソールは、完全に機能するJavaScriptランタイム環境であることを忘れないでください。これは、変数を見るだけに限定されないことを意味します。 ko.contextForの出力を保存し、コンソールから直接ビューモデルを操作できます。 var root = ko.contextFor($0).$root; root.addContact();を試して、何が起こるかを確認してください:-)

楽しいデバッグ!

17

本当にシンプル私が使用しているものをチェックしてください:

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

別の迷惑なことは、未定義の値にバインドしようとしているときです。上記の例で、データオブジェクトは{value: 'some text'}ではなく{}であると想像してください。この場合、問題が発生しますが、次のTweakを使用すると問題ありません。

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

これらのエラーを視覚化するために、knockthrough.jsというgithubプロジェクトを作成しました。

https://github.com/JonKragh/knockthrough

バインディングエラーを強調表示し、そのノードのデータコンテキストのダンプを提供します。

ここでサンプルを試すことができます: http://htmlpreview.github.io/?https://github.com/JonKragh/knockthrough/blob/master/default.htm

enter image description here

SOの優れたノックアウトコードのサンプルを提供してくれたRP Niemeyerに感謝します。

5
Jon Kragh

最も簡単な方法バインディングに渡されるデータを確認するには、データをコンソールにドロップします。

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

Knockoutはテキストバインディングの値を評価し(実際にはここで任意のバインディングを使用できます)、$ dataをコンソールブラウザーパネルにフラッシュします。

3
Dmitry Pavlov

他のすべての答えはうまくいきます。私がやりたいことを追加しています。

ビューで(ViewModelを既にバインドしていると仮定):

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

ノックアウトコード:

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

これにより、デバッガーでコードが一時停止し、elementおよびvalueAccessor()に貴重な情報が含まれます。

2
Aditya M P

Visual Studioで開発しており、IEが好きな場合は、data-bind="somebinding:(function(){debugger; return bindvalue; })()"が好きです。evalファイルではなく、すべてのバインディングを使用してスクリプトに移動するので、エコー関数が好きです。 $ context $ data(Chromeでもこれを使用しています);

1
Filip Cordas

これは私のために働く:

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