【问题标题】:Prevent knockout from applying bindings to elements that are not visible防止敲除将绑定应用于不可见的元素
【发布时间】:2015-10-09 18:15:16
【问题描述】:

我正在渲染一个大型递归数据结构,并试图让用户能够切换该结构中单个元素的编辑。由于编辑器绑定被应用于所有元素,即使它们还不可见,我在应用绑定时遇到性能问题。

<div data-bind="visible: isEditable()">
    <textarea data-bind="kendoEditor: { value: name }" > </textarea>
    <button type="button" data-bind="click: toggleEdit(false)">Update</button>
</div>

如果您查看以下示例,它似乎可以正常工作。您可以单击一个元素,它将启用一个编辑器,您可以单击更新,更改将被应用。

jsfiddle 1

但是,如果您查看以下示例,其中我添加了更多数据,由于将 kendoEditing 绑定应用于列表中的所有元素,初始加载非常慢。

jsfiddle 2

有什么方法可以防止绑定应用到还不可见的元素上?

【问题讨论】:

    标签: knockout.js knockout-3.0 knockout-kendo


    【解决方案1】:

    Roy 的回答可能会更好,但是是的,有一种方法可以防止将绑定应用于后代元素。为此,您需要使用 init 进行自定义绑定,它会返回:

    return { controlsDescendantBindings: true };
    

    以后可以使用

    ko.applyBindingsToDescendants(bindingContext, element)
    

    应用绑定。

    例如这样:

    ko.bindingHandlers.myVisible = {
        init: function(element, valueAccessor) {
            var visible = ko.unwrap(valueAccessor());
          if (visible) {
            $(element).show();
            $(element).data('bindingsApplied', true);
          } else {
            $(element).hide();
            $(element).data('bindingsApplied', false);
            return { controlsDescendantBindings: true };
          }
        },
        update: function(element, valueAccessor, allBindings, viewModel, bindingContext) {
            var visible = ko.unwrap(valueAccessor());
            if (visible) {
                if (!$(element).data('bindingsApplied')) {
                    ko.applyBindingsToDescendants(bindingContext, element);
                    $(element).data('bindingsApplied', true);
                }
                $(element).show();
            } else {
                $(element).hide();
            }
        }
    }
    

    Fiddle

    Documentation

    【讨论】:

      【解决方案2】:

      您提前做了很多切换,因为您的点击绑定应该得到一个函数,而不是一个 sn-p 代码。这是一个常见的错误。

      为避免绑定一百万个编辑器,您可以只交换模板而不是可见和不可见元素:

      <ul data-bind="template: { name: 'itemTmpl', foreach: Items }"></ul>
      <script id="itemTmpl" type="text/html">
      <li>
          <div data-bind="template: isEditable() ? 'editable' : 'notEditable'"></div>
          <ul data-bind="template: { name: 'itemTmpl', foreach: $data.items }"></ul>
      </li>
      </script>
      <script id="notEditable" type="text/html">
          <span data-bind="html: name, click: toggleEdit.bind(null,true)">
          </span>
      </script>
      <script id="editable" type="text/html">
          <textarea data-bind="kendoEditor: { value: name }"></textarea>
          <button type="button" data-bind="click: toggleEdit.bind(null, false)">Update</button>
      </script>
      

      Updated Fiddle

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-05-14
        • 2015-09-21
        • 2017-08-17
        • 1970-01-01
        • 2011-01-15
        • 2012-05-06
        相关资源
        最近更新 更多