我试图在初始ko.applyBindings();
之后让Knockout组件绑定,这样我就可以动态添加自定义元素。
在我的原始帖子中,我提到通过ajax加载内容,但是当使用jQuery append
之类的东西将自定义元素添加到DOM时,会出现问题。
以下是一个例子:
$(function() {
// Register a simple widget:
ko.components.register('like-widget', {
template: '<div class="alert alert-info">This is the widget</div>'
});
// Apply bindings
ko.applyBindings();
// Wire up 'add' button:
$('#btnAdd').on('click', function() {
$('#addZone').append("<like-widget></like-widget>");
});
});
&#13;
<link data-require="bootstrap-css@*" data-semver="3.2.0" rel="stylesheet" href="http://maxcdn.bootstrapcdn.com/bootstrap/3.2.0/css/bootstrap.min.css" />
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.2.0/knockout-min.js"></script>
<body>
Here's a widget, declared inline:
<like-widget></like-widget>
<button id='btnAdd'>Add a new widget to the grey box:</button>
<br/><br/>
<div id='addZone' class="well">
Widgets will be appended here
</div>
<p>When you run this code, the widget custom element is indeed added to the box (see source) but the widget's template is not bound, so nothing appears. How do I get it to bind/appear?</p>
</body>
&#13;
我已成功创建了我的新组件<mynew-widget></mynew-widget>
我已经看到了用它们加工页面的乐趣,一切都很美妙......直到我加载了包含<mynew-widget></mynew-widget>
的新内容(例如一个装有AJAX的模态弹出窗口)。没有任何事情发生。
这是Knockout的限制还是我错误连接了什么?
请告诉我它是后者 - 因为我爱不必担心何时/何地调用ApplyBindings以及DOM的哪些部分。
通过思考,我知道淘汰赛需要注意到自定义元素已添加到DOM中 - 但我希望它可能只适用于jQuery&#39; $().on(...)
&#39;那种方式。
答案 0 :(得分:20)
组件绑定并非神奇地发生:当你致电ko.applyBindings();
时就会发生这种情况。此时,绑定的HTML将搜索组件,并绑定它们。
稍后,当您向页面动态添加新组件时,它不受约束,除非您明确绑定它。因此,在您的代码中,组件完全被忽略。
如上所述,您需要做的是明确绑定它。但是您必须考虑到您无法绑定已绑定的节点。但是,使用jquery创建节点非常容易,将其附加到DOM并绑定它。有一种语法可以指定viewmodel以及要将其绑定到的节点:ko.applyBindings(viewModel, node);
Here you have a full working sample in jsfiddle。这是小提琴中的代码:
HTML:
这是一个内联声明的小部件:
<button id='btnAdd'>Add a new widget to the grey box:</button>
<br/><br/>
<div id='addZone' class="well">
Widgets will be appended here
</div>
JavaScript的:
ko.components.register('like-widget', {
template: '<div class="alert alert-info">This is the widget</div>'
});
ko.applyBindings()
$('#btnAdd').on('click', function() {
// Create your widget node
var $newWidget = $('<like-widget>');
// Append it to your "append area"
$('#addZone').append($newWidget);
// Apply bindings to the newly added node
ko.applyBindings({}, $newWidget[0]);
});
注意:在调用apply bindings时,我传递一个空的objet:不传递null,否则你会收到错误。如果您的模板包含一个视图模型,它将独立于传递的视图模型使用。
注意:$ newWidget是一个jquery对象。 $ newWidget [0]是jQuery对象的第一个(也是唯一的,在本例中)DOM元素,如applyBindings所需