我有一个 View 显示给定位置所有员工的小编辑表单,一个在另一个下面。为每个员工显示的控件之一是 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。
当我加载这些选择列表被注释掉的页面时,它会在 <2 秒内呈现。减速是由于 [我的错误设计] 让 KO 重复构建 150 个项目的选择列表 79 次。由于它们是完全相同的列表,每个列表都绑定(bind)到不同员工的 reassign_to_locationuuid 属性,我想知道是否可以让它运行得更快。
这对 Google 来说是一个艰难的过程,因为:
- 在 knockout.js 中使用多选列表搜索会显示大量关于允许多选的选择列表的信息
- 使用 reuse template in knockout.js 进行搜索 可以找到很多关于命名模板的有用信息
我尝试使用命名模板,但了解到这些似乎适用于您想要将不同数据传递到同一布局的情况——我每次都传递相同的数据。
当我搜索 knockout.js performance 时,我找到了 Ryan Niemeyer 的 http://www.knockmeout.net/2012/06/knockoutjs-performance-gotcha-3-all-bindings.html
为了确定那里描述的问题(所有绑定(bind)同时触发)是否也是我的问题,我从 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: Initially selected value being overwritten -- 因为我昨天找到了这个解决方案,它帮助我完成了上面的重复 knockout 测试(它并没有更快)。
鉴于当页面加载时每个员工的 reassign_to_locationuuid 属性开始时为 null,并且当 reassignLocation 事件触发时,对这些列表中的任何一个的第一次更改将离开此页面,我觉得我做错了什么。
- 在这种情况下,我能否让 KO 只完成其大部分工作一次而不是 79 次?
- 我是否在不该使用 KO 的情况下使用了这部分?也许我不需要这些列表中的所有丰富的 KO 绑定(bind)善良?
- 某些列表构建是否可以以某种方式异步发生?
最佳答案
是的,可以为每个人重复使用相同的位置列表。我通过剥离一些属性简化了你的任务,并编写了你的问题的示例实现。
300 个位置和 100 个人只加载一次 (onload)。每个人的位置列表不需要为每个人单独呈现,因为人员数据会保留和跟踪位置 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()
});
关于performance - 如何在 Knockout.js 中重用选择列表以获得更好的性能?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18301001/