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
に渡されます。
開発にChromeを使用している場合、開発者に直接バインディングコンテキストを表示する Knockoutjsコンテキストデバッガー と呼ばれる非常に優れた拡張機能があります(私は提携していません)。ツールの要素パネル。
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">
利点
私は役に立つことができる別のものを見つけました。私はいくつかのバインディングをデバッグしていて、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>
>=
アイコンをクリックするか、Chrome Developerツールバーの[コンソール]タブを開くか、を押します。 Ctrl+Shift+Jko.dataFor($0)
ko.contextFor($0)
このトリックは、 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();
を試して、何が起こるかを確認してください:-)
楽しいデバッグ!
本当にシンプル私が使用しているものをチェックしてください:
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>
これらのエラーを視覚化するために、knockthrough.jsというgithubプロジェクトを作成しました。
https://github.com/JonKragh/knockthrough
バインディングエラーを強調表示し、そのノードのデータコンテキストのダンプを提供します。
ここでサンプルを試すことができます: http://htmlpreview.github.io/?https://github.com/JonKragh/knockthrough/blob/master/default.htm
SOの優れたノックアウトコードのサンプルを提供してくれたRP Niemeyerに感謝します。
最も簡単な方法バインディングに渡されるデータを確認するには、データをコンソールにドロップします。
<div data-bind="text: console.log($data)"></div>
Knockoutはテキストバインディングの値を評価し(実際にはここで任意のバインディングを使用できます)、$ dataをコンソールブラウザーパネルにフラッシュします。
他のすべての答えはうまくいきます。私がやりたいことを追加しています。
ビューで(ViewModelを既にバインドしていると仮定):
<div data-bind="debugger: $data"></div>
ノックアウトコード:
ko.bindingHandlers.debugger = {
init: function (element, valueAccessor) {
debugger;
}
}
これにより、デバッガーでコードが一時停止し、element
およびvalueAccessor()
に貴重な情報が含まれます。
Visual Studioで開発しており、IEが好きな場合は、data-bind="somebinding:(function(){debugger; return bindvalue; })()"
が好きです。evalファイルではなく、すべてのバインディングを使用してスクリプトに移動するので、エコー関数が好きです。 $ context $ data(Chromeでもこれを使用しています);
これは私のために働く:
<div data-bind="text: function(){ debugger; }()"></div>