将数据绑定到dynamic生成的元素上
如何才能使淘汰赛数据绑定工作在dynamic生成的元素? 例如,我在div中插入一个简单的htmlselect菜单,并希望使用knockout选项绑定来填充选项。 这是我的代码看起来像:
$('#menu').html('<select name="list" data-bind="options: listItems"></select>');
但是这种方法不起作用。 有任何想法吗?
如果在绑定viewmodel之后即时添加此元素,则它将不在viewmodel中,并且不会更新。 你可以做两件事之一。
- 将元素添加到DOM,并通过调用
ko.applyBindings();
重新绑定它ko.applyBindings();
再次 - 或者从一开始就将列表添加到DOM,并将视图模型中的选项集合留空。 淘汰赛将不会呈现,直到您稍后将选项添加到选项。
淘汰赛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”属性dynamic注入html元素。 然后也评估添加的子元素,即它们的数据绑定属性。
重写html绑定代码或创build一个新的。 因为html绑定可以防止dynamichtml中的“注入绑定”:
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()); } };
对于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); } };
编辑:看起来,这不工作从版本2.3 IIRC指出由LosManos
你可以使用myViewModel添加另一个observable到你的viewmodel [newObservable] = ko.observable('')
之后,再次调用ko.applyBindings。
这是一个简单的页面,我可以在其中添加段落,并且新的视图模型和绑定工作完美无缺。 复制到一个html文件并在浏览器中运行。
<!DOCTYPE HTML> <html> <head> <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script> <script src="http://ajax.aspnetcdn.com/ajax/knockout/knockout-2.2.1.js"></script> </head> <body> <div id="placeholder"> <p data-bind="text: paragraph0"></p> </div> <a id="add" href="#">Add paragraph</a> <script type="text/javascript"> // 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> </body> </html>
这是一个古老的问题,但这是我希望最新的答案(淘汰赛3.3.0):
当使用敲除模板或自定义组件将元素添加到预先绑定的可观察集合时,淘汰将自动绑定所有内容。 你的例子看起来像一个可观察的菜单项集合将开箱即用。
基于这个现有的答案 ,我已经完成了一些类似于你最初的意图的事情:
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
方法的viewModel
参数。
结帐这个答案: 如何定义一个自定义淘汰赛选项绑定与预定义的文本和值选项
ko.applyBindingsToNode
特别有用。