在我的真实网络应用程序中,我有一个显示文件夹的树,在某些情况下,我在jQuery UI对话框中显示此树。我已经删除了所有可能的东西,并在这个小提琴中提出了一个问题的例子:
http://jsfiddle.net/shopguy/gRbef/
如果单击按钮1,则会切换对话框可见性。
如果单击按钮2,则会切换内嵌(无对话框)列表可见性。
在Firefox中进行大部分测试。单击按钮1大约需要1.5秒,以显示或隐藏(即使隐藏速度很慢)。点击按钮2几乎是即时的。
这是jQuery UI Dialog的问题。在每个隐藏/显示的DOM上做了很多吗?或者它只是一个问题,因为我在模板中有它? KO是否因为它在这样的模板中而重新创建dom?
两种情况都使用模板,但对话框版本有一个额外的模板,用于对话框本身。虽然他们都使用子文件夹的模板...因为我不确定如何使用KO进行递归树状布局。
这是来自小提琴的主要HTML,显示我的对话框/树形布局:
<div data-bind="jqDialog: {autoOpen: false, modal: false, width: 350, height: 400, minWidth: 350, minHeight: 300 }, template: { name: 'folderDetailsTemplate' } , openDialog: dlg1"></div>
<script type="text/html" id="folderDetailsTemplate">
List<br />
<ul data-bind="template: { name: 'tmpl1', foreach: folders}"></ul>
</script>
<script type="text/html" id="tmpl1">
<li>
<a data-bind="visible: expanded">-</a>
<a data-bind="visible: !expanded">+</a>
<a>
<span data-bind="text: name"></span>
</a>
<ul data-bind="template: { name: 'tmpl1', foreach: folders}">
</ul>
</li>
</script>
这是剧本:
ko.bindingHandlers.jqDialog = {
init: function (element, valueAccessor) {
var options = ko.utils.unwrapObservable(valueAccessor());
$(element).dialog(options);
}
};
ko.bindingHandlers.openDialog = {
update: function (element, valueAccessor) {
var value = ko.utils.unwrapObservable(valueAccessor());
if (value) {
$(element).dialog("open");
} else {
$(element).dialog("close");
}
}
}
function Folder(i, l) {
this.name = "Test Folder " + i;
this.folders = ko.observableArray();
this.expanded = true;
if (i < 4 && l < 4) {
var fs = new Array();
for (var x = 0; x < 2; x++) {
var f = new Folder(x, l + 1);
fs.push(f);
}
this.folders(fs);
}
}
var vm = function () {
var self = this;
self.folders = ko.observableArray();
var fs = new Array();
for (var x = 0; x < 50; x++) {
var f = new Folder(x, 0);
fs.push(f);
}
self.folders(fs);
self.dlg1 = ko.observable();
self.list1 = ko.observable();
self.test1 = function () {
self.dlg1(!self.dlg1());
}
self.test2 = function () {
self.list1(!self.list1());
}
}
$(function () {
ko.applyBindings(new vm());
});
答案 0 :(得分:1)
让它变慢的原因是openDialog
和template
绑定在同一元素的绑定字符串中组合在一起。因此,每次更新openDialog
时,模板绑定也会更新并重新呈现模板。我喜欢将模板绑定放在嵌套的注释绑定中,如下所示:
<div data-bind="jqDialog: {autoOpen: false, modal: false, width: 350, height: 400, minWidth: 350, minHeight: 300 }, openDialog: dlg1">
<!-- ko template: 'folderDetailsTemplate' --><!-- /ko -->
</div>
这里的详细信息非常详细:http://www.knockmeout.net/2012/06/knockoutjs-performance-gotcha-3-all-bindings.html