1

在下面的代码中,我正在更新我的淘汰模型属性SearchResults,然后我正在重新计算我的 html 中所有列的大小。我知道该_resizeColumns功能正常工作。然而,它是在 DOM 使用搜索结果更新之前运行的。_resizeColumns我已经通过用黄色更新所有 div 上的背景颜色来验证它正在被调用。模型更新之前存在的 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

更新 我不认为淘汰赛是异步运行的。我相信这是网络浏览器本身异步更新 DOM。

更新 2_resizeColumns()函数在直接从$(document).ready().

更新 3 我有两个版本,_resizeColumns()一个使用 jquery 选择器来获取和设置宽度,另一个在获取宽度时存储到二维数组中,并在设置它们时访问该二维数组。二维数组版本的执行速度更快。二维数组版本也导致了我上面原始问题中的问题。仅 jquery 版本没有。

4

2 回答 2

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;
                });
            });
        }
    }
};
于 2013-10-02T19:36:29.300 回答
1

您的问题的答案是否定的,Knockout 不会异步执行绑定,除非您明确强制它。默认情况下,它会在继续您的下一个声明之前通知所有订阅者。

http://jsfiddle.net/uVgdF/

可以这样看——

self.updateSomethings = function () {
    self.somethings.push(new something('William', 1234432));
    alert('binding complete');
}        
于 2013-10-02T18:55:23.493 回答