0

我有一个显示 20 行数据的 knockout.js 视图。每行都有一个与 knockout.js 绑定的 select 2 控件。(下面你可以看到我的绑定处理程序)

现在每个 select 2 指向同一个 items 数组。这个数组有大约 10.000 个条目。这会导致整个页面变慢(大约 2-3 秒冻结时间)

我正在考虑仅在用户单击该行时加载选项。像这样:

 self.setSelectedRow = function (entry) {
        entry.options(allOptions);
        var value = entry.intialValue;
        entry.StationdId(value);
    };

在此之后,选择 2 是可扩展的,我可以选择选项,但不应用初始值。关于我做错了什么的任何提示?

绑定处理程序:

ko.bindingHandlers.select2 = {
    init: function (el, valueAccessor, allBindingsAccessor, viewModel) {
        ko.utils.domNodeDisposal.addDisposeCallback(el, function () {
            $(el).select2('destroy');
        });

        var allBindings = allBindingsAccessor(),
            select2 = ko.utils.unwrapObservable(allBindings.select2);

        $(el).select2(select2);
    }
};
4

2 回答 2

1

绑定处理程序通常有两个功能:

  • 创建绑定时调用的init函数(请注意,可以多次调用它,因为每次创建/重新创建绑定时都会调用它——例如:当节点在if绑定中时)。这个函数应该包含设置绑定的代码(你做得很好)
  • update每次绑定标记中的可观察对象更改时调用的函数。请注意,此函数也在 init 上调用(就在init函数之后),因此在某些情况下您不需要init函数。

custom绑定文档中的更多信息。

在你的情况下,我认为这个init功能很好。

问题是没有设置任何东西来处理你的 observables 的变化。

您可以添加一个update看起来像这样的函数(未经测试):

ko.bindingHandlers.select2 = {
    init: function (el, valueAccessor, allBindingsAccessor, viewModel) {
        /* your code is fine */
    },
    update: function (el, valueAccessor, allBindingsAccessor, viewModel) {
        var allBindings = allBindingsAccessor(),
            select2 = ko.utils.unwrapObservable(allBindings.select2);
        $(el).select2(select2); //update the select2
    }
};
于 2014-07-17T10:22:17.517 回答
1

除非您使用的是非常过时的knockout版本,否则我认为您的绑定语法是错误的。

这部分是错误的:

var allBindings = allBindingsAccessor(),
  select2 = ko.utils.unwrapObservable(allBindings.select2);

如果您阅读http://knockoutjs.com/documentation/custom-bindings.html 正确的使用方法allBindingsAccessor(无论如何它应该被命名为 allBindings)是

var select2 = allBindingsAccessor.get('select2') || {};

但即使这是不必要的,valueAccessor 也会为您提供当前绑定 ( select2) 下的内容。

所以试试这个:

ko.bindingHandlers.select2 = {
    init: function (el, valueAccessor, allBindingsAccessor, viewModel) {
        ko.utils.domNodeDisposal.addDisposeCallback(el, function () {
            $(el).select2('destroy');
        });

        $(el).select2(ko.unwrap(valueAccessor()));
    }
};
于 2014-07-17T12:44:19.593 回答