【问题标题】:Can you call ko.applyBindings to bind a partial view?可以调用 ko.applyBindings 来绑定局部视图吗?
【发布时间】:2011-11-12 15:45:59
【问题描述】:

我正在使用 KnockoutJS 并且有一个主视图和视图模型。我想要一个对话框(jQuery UI 对话框)弹出另一个视图,该视图绑定一个单独的子视图模型。

对话框内容的 HTML 是使用 AJAX 检索的,因此我希望能够在请求完成后调用 ko.applyBindings,并且我想将子视图模型绑定到通过 ajax 加载的 HTML 的部分内部对话框 div。

这真的可能吗,还是我需要在页面最初加载时加载我的所有视图和视图模型,然后调用一次ko.applyBindings

【问题讨论】:

    标签: ajax html knockout.js


    【解决方案1】:

    您应该查看with 绑定以及controlsDescendantBindings http://knockoutjs.com/documentation/custom-bindings-controlling-descendant-bindings.html

    【讨论】:

    • 看起来很复杂。 ko 3.0 会更简单吗?
    【解决方案2】:

    虽然 Niemeyer 的答案是对该问题的更正确答案,但您也可以执行以下操作:

    <div>
      <input data-bind="value: VMA.name" />
    </div>
    
    <div>
      <input data-bind="value: VMB.name" />
    </div>
    
    <script type="text/javascript">
      var viewModels = {
         VMA: {name: ko.observable("Bob")},
         VMB: {name: ko.observable("Ted")}
      };
    
      ko.applyBindings(viewModels);
    </script>
    

    这意味着您不必指定 DOM 元素,甚至可以将多个模型绑定到同一个元素,如下所示:

    <div>
      <input data-bind="value: VMA.name() + ' and ' + VMB.name()" />
    </div>
    

    【讨论】:

    • 您也可以使用“with”将页面区域分配给各个模型 - data-bind="with:VMA"
    • @flamingpenguin:是的,但with 并不便宜,请参阅:link
    【解决方案3】:

    我已经设法在运行时将自定义模型绑定到元素。代码在这里:http://jsfiddle.net/ZiglioNZ/tzD4T/457/

    有趣的是,我将 data-bind 属性应用于我没有定义的元素:

        var handle = slider.slider().find(".ui-slider-handle").first();
        $(handle).attr("data-bind", "tooltip: viewModel.value");
        ko.applyBindings(viewModel.value, $(handle)[0]);
    

    【讨论】:

    • 在使用 ko 2.3 时遇到问题,上面的代码在我应用全局 ko.applyBindings() 时调用的客户处理程序中。所以现在我收到错误“您不能多次将绑定应用于同一个元素。”。我仍在试图弄清楚为什么会出现错误。我们不能多次将绑定应用于同一个变量,每次应用于不同的元素吗?
    • 这里是 ko 2.3 无法工作的版本:jsfiddle.net/ZiglioNZ/tzD4T/458
    • 在对局部视图调用 applyBinding 之前添加对 ko.cleanNode() 的调用似乎没有帮助:jsfiddle.net/ZiglioNZ/tzD4T/459
    • 已解决:我什至不需要调用 applyBindings!
    • 我刚刚编辑了 knockoutjs 源代码并评论了函数 twrows 的部分“你不能多次将绑定应用于同一个元素。”,现在一切正常......我知道这是一个肮脏的解决方案,但我是图书馆的新手,所以我不知道如何不多次应用它来解决我的问题。
    【解决方案4】:

    ko.applyBindings 接受第二个参数,该参数是用作根的 DOM 元素。

    这会让你做类似的事情:

    <div id="one">
      <input data-bind="value: name" />
    </div>
    
    <div id="two">
      <input data-bind="value: name" />
    </div>
    
    <script type="text/javascript">
      var viewModelA = {
         name: ko.observable("Bob")
      };
    
      var viewModelB = {
         name: ko.observable("Ted")
      };
    
      ko.applyBindings(viewModelA, document.getElementById("one"));
      ko.applyBindings(viewModelB, document.getElementById("two"));
    </script>
    

    因此,您可以使用此技术将 viewModel 绑定到加载到对话框中的动态内容。总的来说,您只需要注意不要在同一个元素上多次调用 applyBindings,因为您会附加多个事件处理程序。

    【讨论】:

    • 如果您还想在以后的某个时候删除绑定,您可以调用ko.cleanNode(document.getElementById("one") 进行清理或调用ko.removeNode(document.getElementById("one") 进行清理并从 DOM 中删除节点。跨度>
    • 请注意cleanNoderemoveNode 不会删除事件处理程序,因此请谨慎使用。在某些情况下,最好在这些区域上使用templatewith 绑定,以便渲染新元素。
    • 这是目前KO所缺乏的东西。我们并不特别打算让人们“重新绑定”部分。但是,如果引用了 jQuery,KO 确实使用 jQuery 附加事件,因此您可以使用 $(element).unbind(); 删除所有处理程序。
    • 这些函数(applyBindings、cleanNode、removeNode)记录在哪里?我在 knockoutjs.com 上找不到他们的函数签名。
    • 如果这在文档中很容易找到,那就太好了。我什至没有看到提及它。
    猜你喜欢
    • 2013-09-23
    • 2011-11-23
    • 2019-08-11
    • 1970-01-01
    • 1970-01-01
    • 2022-01-17
    • 1970-01-01
    • 2019-01-17
    • 1970-01-01
    相关资源
    最近更新 更多