52

動的に生成された要素でノックアウトデータバインドを機能させるにはどうすればよいですか?たとえば、div内に単純なhtml選択メニューを挿入し、ノックアウトオプションバインディングを使用してオプションを設定したいとします。これは私のコードがどのように見えるかです:

$('#menu').html('<select name="list" data-bind="options: listItems"></select>');

しかし、この方法は機能しません。何か案は?

4

8 に答える 8

33

ビューモデルをバインドした後でこの要素をオンザフライで追加すると、ビューモデルに含まれず、更新されません。あなたは2つのことのうちの1つをすることができます。

  1. 要素をDOMに追加し、ko.applyBindings();もう一度呼び出して再バインドします
  2. または、リストを最初からDOMに追加し、ビューモデルのオプションコレクションを空のままにします。後でその場でオプションに要素を追加するまで、ノックアウトはそれをレンダリングしません。
于 2012-06-16T21:46:36.017 に答える
15

ノックアウト3.3

ko.bindingHandlers.htmlWithBinding = {
          'init': function() {
            return { 'controlsDescendantBindings': true };
          },
          'update': function (element, valueAccessor, allBindings, viewModel, bindingContext) {
              element.innerHTML = valueAccessor();
              ko.applyBindingsToDescendants(bindingContext, element);
          }
    };

上記のコードスニペットを使用すると、「htmlWithBinding」プロパティを使用してhtml要素を動的に挿入できます。追加された子要素も評価されます...つまり、データバインド属性です。

于 2015-07-14T09:13:28.660 に答える
11

HTMLバインディングコードを書き直すか、新しいコードを作成します。htmlバインディングは、動的htmlでの「挿入されたバインディング」を防ぐため:

ko.bindingHandlers['html'] = {
  //'init': function() {
  //  return { 'controlsDescendantBindings': true }; // this line prevents parse "injected binding"
  //},
  'update': function (element, valueAccessor) {
    // setHtml will unwrap the value if needed
    ko.utils.setHtml(element, valueAccessor());
  }
};

于 2015-04-13T12:38:27.910 に答える
4

編集: LosManosが指摘したバージョン2.3 IIRC以降、これは機能しないようです

myViewModel [newObservable] = ko.observable('')を使用して、ビューモデルに別のオブザーバブルを追加できます。

その後、ko.applyBindingsを再度呼び出します。

これは、段落を動的に追加し、新しいビューモデルとバインディングが問題なく機能する簡単なページです。

// myViewModel starts only with one observable
    	var myViewModel = {
    	    paragraph0: ko.observable('First')
    	};
    
    	var count = 0;
    
    	$(document).ready(function() {
    		ko.applyBindings(myViewModel);
    
    		$('#add').click(function() {
    			// Add a new paragraph and make the binding
    			addParagraph();
    			// Re-apply!
    			ko.applyBindings(myViewModel);			
    			return false;	
    		});
    	});
    
    	function addParagraph() {
    		count++;
    		var newObservableName = 'paragraph' + count;
    	    $('<p data-bind="text: ' + newObservableName + '"></p>').appendTo('#placeholder');
    		
    	    // Here is where the magic happens
    		myViewModel[newObservableName] = ko.observable('');
    		myViewModel[newObservableName](Math.random());
    
    		// You can also test it in the console typing
    		// myViewModel.paragraphXXX('a random text')
    	}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/2.2.1/knockout-min.js"></script>

<div id="placeholder">
    <p data-bind="text: paragraph0"></p>
</div>
    
<a id="add" href="#">Add paragraph</a>

于 2013-04-16T18:10:20.910 に答える
4

v3.4.0の場合、以下のカスタムバインディングを使用します。

ko.bindingHandlers['dynamicHtml'] = {
    'update': function (element, valueAccessor, allBindings, viewModel, bindingContext) {
        // setHtml will unwrap the value if needed
        ko.utils.setHtml(element, valueAccessor());
        ko.applyBindingsToDescendants(bindingContext, element);
    }
};
于 2016-02-26T14:52:23.693 に答える
2

これは古い質問ですが、これが私の最新の回答(ノックアウト3.3.0)です。

ノックアウトテンプレートまたはカスタムコンポーネントを使用して、事前にバインドされた監視可能なコレクションに要素を追加する場合、ノックアウトはすべてを自動的にバインドします。あなたの例は、観察可能なメニュー項目のコレクションが箱から出して仕事をするように見えます。

于 2015-04-27T18:41:11.193 に答える
1

この既存の答えに基づいて、私はあなたの最初の意図に似た何かを達成しました:

function extendBinding(ko, container, viewModel) {
    ko.applyBindings(viewModel, container.children()[container.children().length - 1]);
}

function yourBindingFunction() {
    var container = $("#menu");
    var inner = $("<select name='list' data-bind='options: listItems'></select>");
    container.empty().append(inner);


    extendBinding(ko, container, {
        listItems: ["item1", "item2", "item3"]
    });
}

これがJSFiddleで遊ぶことです。

注意してください、新しい要素がdomの一部になると、への呼び出しでそれを再バインドすることはできませんko.applyBindings-それが私が使用する理由ですcontainer.empty()。新しい要素を保持し、ビューモデルの変更に応じて変更する必要がある場合は、メソッドのviewModelパラメーターにobservableを渡します。extendBinding

于 2014-11-07T20:14:14.997 に答える
0

この回答を確認してください:事前定義されたテキストと値のオプションを使用して、カスタムノックアウトの「オプションバインディング」を定義するにはどうすればよいですか

ko.applyBindingsToNode特に便利です。

于 2017-11-15T12:44:12.230 に答える