敲除组件(不)绑定新内容

时间:2014-11-25 22:18:20

标签: javascript jquery knockout.js dom-manipulation

编辑问题和示例

我试图在初始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;
&#13;
&#13;

原帖

我已成功创建了我的新组件<mynew-widget></mynew-widget>

我已经看到了用它们加工页面的乐趣,一切都很美妙......直到我加载了包含<mynew-widget></mynew-widget>的新内容(例如一个装有AJAX的模态弹出窗口)。没有任何事情发生。

这是Knockout的限制还是我错误连接了什么?

请告诉我它是后者 - 因为我不必担心何时/何地调用ApplyBindings以及DOM的哪些部分。

通过思考,我知道淘汰赛需要注意到自定义元素已添加到DOM中 - 但我希望它可能只适用于jQuery&#39; $().on(...)&#39;那种方式。

1 个答案:

答案 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所需