1

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

<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

有什么方法可以防止绑定应用于尚不可见的元素?

4

2 回答 2

3

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();
        }
    }
}

小提琴

文档

于 2015-10-09T19:32:56.623 回答
2

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

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

<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>

更新小提琴

于 2015-10-09T18:38:27.600 回答