在下面的代码中,我正在更新我的knockout模型属性SearchResults
,然后我重新计算我的html中所有列的大小。我知道_resizeColumns
函数可以正常工作。但是,在使用搜索结果更新DOM之前,它正在运行。我已经通过更新所有带黄色的div的背景颜色来验证是否正在调用_resizeColumns
。在模型更新之前存在的div被设置为黄色,但搜索结果不是。
$.ajax({
type: 'POST',
url: 'foo.com',
data: postData,
contentType: 'application/json; charset=utf-8',
dataType: 'json',
processData: true,
success: function(data) {
model.SearchResults(data.d); // updates the DOM with the search results via knockout.js
_resizeColumns(); // does not resize the columns because they haven't been added to the DOM yet
},
error: function() { alert('error'); }
});
搜索结果会添加到DOM中,只是在我调用_resizeColumns
更新 我不认为淘汰赛是异步运行的。我相信它是Web浏览器本身异步更新DOM。
更新2
直接从_resizeColumns()
调用$(document).ready()
函数。
更新3
我有两个版本_resizeColumns()
,一个使用jquery选择器来获取和设置宽度,另一个在获取宽度时存储到二维数组中,并在设置时访问该二维数组。 2d阵列版本执行得更快。 2d阵列版本也导致我上面的原始问题中的问题。仅jquery版本没有。
答案 0 :(得分:2)
在我的应用程序中,我遇到了类似的问题 - 我需要在Knockout呈现内容后设置列宽。我的解决方案是创建一个自定义绑定,我可以放在<table>
元素上,每当表更新时都会更新(因为它绑定到同一个可观察数组)。当试图同步运行绑定时,我遇到了麻烦,但它很简单,让它以异步方式运行。这是我的约束力:
ko.bindingHandlers.fixColumnWidths = {
update: function(element, valueAccessor) {
if (ko.utils.unwrapObservable(valueAccessor())) {
setTimeout(function() {
$headings = $(element).find('thead th');
if (!$headings.length) {
$headings = $(element.rows[0].cells);
}
$headings.width('').width(function(index, width) {
return width;
});
});
}
}
};
答案 1 :(得分:1)
你的问题的答案是否定的,Knockout不会异步执行绑定,除非你明确强制它。默认情况下,它会在转到下一个声明之前通知所有订阅者。
这可以这样看 -
self.updateSomethings = function () {
self.somethings.push(new something('William', 1234432));
alert('binding complete');
}