如何使knockout数据绑定对动态生成的元素起作用?例如,我在div中插入一个简单的html选择菜单,并希望使用knockout选项绑定填充选项。这就是我的代码:
$('#menu').html('<select name="list" data-bind="options: listItems"></select>');
但此方法不起作用。有什么想法吗?
答案 0 :(得分:31)
如果在绑定viewmodel后动态添加此元素,则它将不在viewmodel中,并且不会更新。你可以做两件事之一。
ko.applyBindings();
重新绑定它答案 1 :(得分:12)
淘汰赛3.3
ko.bindingHandlers.htmlWithBinding = {
'init': function() {
return { 'controlsDescendantBindings': true };
},
'update': function (element, valueAccessor, allBindings, viewModel, bindingContext) {
element.innerHTML = valueAccessor();
ko.applyBindingsToDescendants(bindingContext, element);
}
};
上面的代码片段允许您使用&#34; htmlWithBinding&#34;动态注入html元素。属性。然后还评估添加的子元素......即它们的数据绑定属性。
答案 2 :(得分:10)
重写html绑定代码或创建一个新的。因为html绑定会阻止&#34;注入绑定&#34;在动态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());
}
};
&#13;
答案 3 :(得分: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);
}
};
答案 4 :(得分:3)
编辑:从LosManos
指出,从版本2.3 IIRC开始,这似乎不起作用您可以使用myViewModel [newObservable] = ko.observable(&#39;&#39;)
为视图模型添加另一个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')
}
&#13;
<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>
&#13;
答案 5 :(得分:2)
这是一个老问题,但这是我希望最新的答案(淘汰3.3.0):
当使用挖空模板或自定义组件向预绑定的可观察集合添加元素时,knockout将自动绑定所有内容。您的示例看起来像一个可观察的菜单项集合,可以开箱即用。
答案 6 :(得分:0)
根据this existing answer,我发现了类似于您最初意图的内容:
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()
的原因。如果您需要保留新元素并在视图模型更改时进行更改,请将observable传递给viewModel
方法的extendBinding
参数。
答案 7 :(得分:0)
查看此答案:How do define a custom knockout 'options binding' with predefined Text and Value options
ko.applyBindingsToNode
特别有用。