2011-11-26 21 views
33

私はko.applyBindings()の後に新しい要素をDOMに注入します。ノックアウトはこれらの新しい要素を認識しません。 これはなぜ起こっているのか理解できます。ノックアウトでインデックス化されていないだけです。knockout.js:バインディングを更新しますか?

最初は、新しい要素を追加した後にko.applyBindings()を呼び出すだけで解決できると思っていましたが、ko.applyBindings()呼び出しごとに、複数回発砲。したがって、5回適用した後、クリック:バインディングが5回実行されるので、これは望ましい解決策ではありません)。

ko.updateBindings()など何かがあります。要素バインディングを更新しますか?

挨拶、 クリス

+1

何をしているのかを示すコードを投稿できますか? –

+0

よく、例えば次のようなものです:$( 'body')。append( 'Click me!'); –

+0

私はそれが役に立つ答えを提供するのに十分なコンテキストであるかどうかはわかりません。私はあなたが何をしようとしているのか理解していますが、コードを完全に理解している(なぜ、新しいDOM要素を注入するのか)、これを処理する最善の方法で答えるのは難しいです。現在のソリューションを見て、誰かが新しい要素を注入する必要がない方法を指摘したり、やりたいことを回避する方法があるかもしれません。 –

答えて

35

あなたは全体のDOMバインディングのために検査されko.applyBindings起動するたびに。結果として、これを複数回実行すると、各要素に対して複数のバインディングが取得されます。あなただけの新しいDOM要素をバインドしたい場合は、applyBindings関数へのパラメータとして、この要素を渡すことができます:あなたがしているもの知らず

Can you call ko.applyBindings to bind a partial view?

+1

はい、これも私が思いついた解決策です:)悲しいことに、私はknockoutjs.comのAPIドキュメントを直接見つけられなかったので、これを見つけるためにkoオブジェクトのリバースエンジニアリングを行う必要がありました.- –

+1

True、いいえAPIのドキュメントですが、それはもっと「覚えやすい」ドキュメントにあります。このページの下半分を見てください:http://knockoutjs.com/documentation/observables.html – ColinE

+0

これが答えではありますか? newElementがviewModelAのDOMのルートであるかのように、viewModelAをnewElementに適用しないでしょうか?私はそれがいくつか、またはほとんどの時間を動作するかを見ることができますが、私はそれがどのように製品の未特定の結果(私は思う)かもしれないかを見ることができます。 –

7

ko.applyBindings(viewModelA, document.getElementById("newElement")); 

この関連の質問を参照してくださいまあまあ、あなたはこれについて間違った方向に行っているようです。あなたのビューはあなたのビューモデルによって駆動されるべきです。したがって、ノックアウトバインディングを適用する必要があるDOM要素を直接追加するべきではありません。

代わりに、ビューの変更を反映するようにビューモデルを更新する必要があります。変更すると、新しい要素が表示されます。

たとえば、$('body').append('<a href="#" data-bind="click: something">Click me!</a>');の場合、ボタンを表示するときにDOM要素を追加するのではなく、ビューモデルを使用してボタンの表示を制御します。

だからあなたのビューモデルは

var viewModel = { clickMeAvailable: ko.observable(false) } 

が含まれており、あなたのHTMLは、あなたはその後、ちょうどviewModel.clickMeAvailable(true)

<a href="#" data-bind="click: something, visible: clickMeAvailable">Click me!</a> 

私をクリックするボタンが利用可能なアプリケーションの状態の変更をあるよう

が含まれています。

ノックアウトの大きな部分は、ビジネスロジックとプレゼンテーションを分離することです。だから私をクリックして私がボタンを含むことを気にしないコードを私をクリックしてください。私がクリックすると、更新はviewModel.clickMeAvailableになります。

たとえば、フォームを有効に入力したときに利用できる保存ボタンがあります。観察可能なビューモデルformValidへの保存ボタンの可視性を結びつけます。

しかし、フォームを有効にした後に変更することにした場合、保存する前に合意しなければならない合意が表示されます。フォームのロジックは変更されません。フォームが有効な場合はまだformValidに設定されています。 formValidが変更されたときに起こることを変更するだけです。

lassombraがこの回答のコメントに指摘しているように、直接的なDOM操作が最善のアプローチである場合があります。たとえば、必要に応じてビューの一部だけを水和したい複雑な動的ページです。しかし、あなたはこれを行うことによってノックアウトが提供する懸念の分離のいくつかをあきらめています。このトレードオフを検討している場合は注意してください。

+0

に、私はそれはあなたがで終わるようにknockoutjsを活用しても意味がない場合があると思います』扱った。その場合、あなたは、特にそれが利用可能なときに/読み込みが完了したために設定し、(おそらくAJAX経由で引き込ま)あなたのネストされたHTMLにバインドされたビューモデルを持っている必要があります。 – Jed

+0

を記録するために、私はこれがあると思います正解。コントロールは、イベント動作から駆動されていない、宣言に拘束されなければならない。ノックアウトはあなたが最小限に迷惑なバグを避けるために一貫性の全体的なアプローチを維持する必要があり、これらの技術の一つである。 –

+3

何眺め、特に大規模なサイトについてすべての可能なビューをデフォルトのページにパックする必要がありますか?確かにそうではありません。サイトの他の「エリア」に移動するときに、ajax経由でビューをロードすることは確かに私は個人的に私が変換しているWebアプリケーションでこれを使用しています。元のアプリケーションはMVC4で、私が追跡していたさまざまな個人管理データ(株式、その他の金融、トドーリスト、連絡先リスト、イベントカレンダー)のビューが異なります。彼らはすべて同じマスターページを使用するので、それらをMVVM /ノックアウトに変換するのはかなり簡単です。 – lassombra

0

私は長い時間前に尋ねたことは知っていますが、私はちょうど同様の問題を偶然見つけました。私は新しい要素をコンテナに追加しようとし、それらにonclick関数を与えようとしました。 最初にあなたがしたことを試して、さらにアプローチを試みたColinErecommended

HTML::

<div id="workspace" data-bind="foreach:nodeArr, click:addNode"> 
<div class="node" data-bind="attr:{id:nodeID},style:{left:nodeX,top:nodeY},text:nodeID, click:$parent.changeColor"></div> 
</div> 

はJavaScript:

<script> 
function ViewModel() { 
var self = this; 
var id = 0; 
self.nodeArr = ko.observableArray(); 
self.addNode = function (data, event) { 
    self.nodeArr.push({ 
     'nodeID': 'node' + id, 
     'nodeX' : (event.offsetX - 25) + 'px', 
     'nodeY' : (event.offsetY - 10) + 'px' 
    }) 
    id++; 
} 
self.changeColor = function(data, event){ 
    event.stopPropagation(); 
    event.target.style.color = 'green'; 
    event.target.style.backgroundColor = 'white'; 
} 
} 
ko.applyBindings(new ViewModel()); 
</script> 

のことができます。これは私が私のために完璧にworkesれ、SamStephensアプローチを試してみましたが、それを思い付いたように、私のための実用的なソリューションではありませんでしたそれで遊んでJS Fiddleを作りました。 これはまだ誰かを助けることを願っています。

+1

まあ、私のために...私はKnockoutJSを放棄しました。 –

+0

@ChristianEngel KOは柔軟性に欠けるものではありません。いくつかのことはKOの方法で行う必要があります(私はまだリバインドする必要があると感じています!)楽しいものですが、[Durandal](http://durandaljs.com) KO) - >ビューをサポートする素晴らしい柔軟性 - 個別のビューは、それぞれのビューが独自のモデルを導入するかモデルの一部を共有するかを手動で部分的にバインドする必要性を効果的に緩和します。今、私が好きではないKOについていくつかのことがありますが、それは柔軟性の欠如とは関係ありません!観測可能なモデルは、一度完全に利用されると非常にフレキシブルです。 – user2246674

+0

@ChristianEngel DOMに注入されるランダムな(外部の)要素を扱うための「ハッキリだが簡単な」方法は、 'if'のような* flow control *バインディングにそれらを挿入することです(この投稿には、 with)、要素が挿入された後にコンテンツを「オン」に切り替えます。新しいサブツリーは、必要に応じてバインドされます。余分なマニュアル 'applyBindings'がありません。また、observableがフローバインディングを制御します。 'withProperties'のような追加のバインディングを使って、スコープのプロパティを絞り込むことができます。 – user2246674

関連する問題