3

我有一个视图显示给定位置的所有员工的小型编辑表单,一个在另一个之下。为每位员工显示的控件之一是 150 个城市的选择列表。该选择列表上的更改事件将员工转移到另一个位置。

<select data-bind="options: $root.locations(),
    optionsCaption: 'Please choose...',
    optionsText: function(item) { return item.locationname(); },
    optionsValue: 'uuid',
    value: reassign_to_locationuuid,
    event: {change: $root.reassignLocation}">
</select>

这工作正常,但最大的位置有 79 人,当该页面加载时,它需要一段时间 - 没什么疯狂的,只有大约 10 秒,我有一个很好的催眠加载动画,当用户等待时。但我想知道如何提高加载速度和我的 Knockout-fu,在这成为一个更大的问题之前。

当我加载带有注释掉这些选择列表的页面时,它会在 <2s 中呈现。放缓是由于 [我的糟糕设计] 让 KO 重复构建包含 150 个项目的选择列表的工作 79 次。由于它们是完全相同的列表,每个列表都绑定到不同员工的 reassign_to_locationuuid 属性,我想知道是否可以让它运行得更快。

这对谷歌来说是一个艰难的过程,因为:

  • 在 knockout.js 中使用多个选择列表进行搜索会在允许多项选择的选择列表上显示大量信息
  • 在 knockout.js 中使用重用模板进行搜索会带来很多关于命名模板的有用信息

我尝试使用命名模板,但了解到这些似乎适用于您希望将不同数据传递到同一布局的情况——我每次都传递相同的数据。

当我搜索knockout.js 性能时,我发现了 Ryan Niemeyer 的 http://www.knockmeout.net/2012/06/knockoutjs-performance-gotcha-3-all-bindings.html

为了确定那里描述的问题(所有绑定同时触发)是否也是我的问题,我从https://github.com/mbest/knockout-repeat下载了 Michael Best 的 knockout-repeat并更改了我的选择列表以使用它方法:

<select data-bind="value: reassign_to_locationuuid, 
                   event: {change: $root.reassignLocation}">
    <option value="">Please choose...</option>
    <option data-bind="repeat: $root.locations()" 
            data-repeat-bind="attr: { value: $item().uuid() }, 
                              text: $item().locationname()">
    </option>
</select>

...但时间几乎相同,所以似乎不是这样。

感谢 Michael & Ryan 回答Knockout with repeat binding:Initial selected value being overwritten —— 因为我昨天发现了这个解决方案,它帮助我完成了上面的敲除重复测试(它并没有更快)。

鉴于页面加载时每个员工的 reassign_to_locationuuid 属性开始为 null,并且当reassignLocation事件触发时,对这些列表中的任何一个的第一次更改将离开此页面,我觉得我做错了什么。

  1. 在这种情况下,我可以让 KO 只做一次而不是 79 次吗?
  2. 我不应该在这部分使用 KO 吗?也许我不需要这些列表中所有丰富的 KO 绑定优点?
  3. 这种列表构建中的一些是否会以某种方式异步发生?
4

1 回答 1

2

是的,可以为每个人重复使用相同的位置列表。我通过剥离一些属性并编写了您的问题的示例实现来简化您的任务。

http://jsfiddle.net/PqqHK/

300 个地点和 100 人只装载一次(装载)。不需要为每个人单独呈现每个人的位置列表,因为人员数据会保留并跟踪位置 ID,并且select在人员更改时选择适当的位置项。

<div data-bind="with: selectedPerson">
    <p>
        <b>Id:</b>
        <span data-bind="text: id"></span>
    </p>
    <p>
        <b>Name:</b>
        <span data-bind="text: name"></span>
    </p>
    <p>
        <b>Location:</b>
        <select data-bind="options: $root.locations,
            optionsValue: 'id',
            optionsText: 'name',
            value: location"></select>
        <i>Select another value to relocate!</i>
    </p>
</div>

人员构造函数:

function Person(id, name, locId) {
    this.id = id;
    this.name = name;
    this.location = ko.observable(locId);
}

模型:

ko.applyBindings(vm = {
    persons: persons,
    locations: locations,
    selectedPerson: ko.observable()
});
于 2013-08-19T12:17:12.177 回答