我在使用KnockoutJS foreach绑定和大型数据集时遇到了问题。目前,我将容器div的“数据”绑定设置为一个函数,该函数执行ajax调用以获取数据,在JS对象中解析它,并将每个结果推送到一个可观察的数组中。
当我的数据集很小(0-50)时,这种方法很有效。但是,一旦我开始有100多条记录,总时间就会急剧增加。我发现只要数据开始处理,浏览器的线程就会被“锁定”,直到所有元素都被解析并添加到数组中。最后,它会将内容加载到dom上并立即“弹出”。
我想知道是否有办法通过延迟将元素加载到DOM中来修改它。具体来说,我希望DOM在处理每个元素时呈现它们,而不是等待所有元素被处理。
由于
答案 0 :(得分:0)
由于您尚未发布代码段,因此我解释了您可以执行的一种可能方法。
您可以更改服务器端代码,以便以能够处理延迟加载的方式返回数据。
然后你需要有一个间隔函数来持续调用一个函数,如果你的最后一个ajax调用返回数据,你在该函数内检查一个标志,然后它调用下一个ajax。
在您的响应中,数据具有跟踪是否有更多数据,总项目等的属性。然后在您的Ajax成功中回调更新observables变量,您可以使用它们发送您的请求数据,如NextPage等,如果没有更多数据,你取消了setInterval函数。
以下是您如何实施此方法的示例(未经测试)
JS:
var YourViewModel = function () {
var self = this ;
var loadMoreTimer;
self.IsMoreItems = ko.observable(false);
self.LoadingMoreInProcess = ko.observable(false);
self.CurrentPage = ko.observable(0);
self.Items = ko.observableArray([]);
self.AutomaticLoadItem = function () {
loadMoreTimer = setInterval(callLoadMore, 500);
}
function callLoadMore() {
if (self.IsMoreItems()) {
if (!self.LoadingMoreInProcess()) {
self.LoadMore();
}
}
}
self.LoadMore = function () {
self.CurrentPage(self.CurrentPage() + 1);
self.LoadingMoreInProcess(true);
data = {requestPage : self.CurrentPage(), numberOfItem : 20, ...}
//your ajax call here
$.ajax({
url:...,
type: ....,
data: data,
success: function(response){
// here you check if there is more data left
if(response.isMoreData){
// set it to false so the next ajax call can be executed.
self.LoadingMoreInProcess(false);
// map through your data and push each item into the observableArray
$.map(response.Items, function (item) {
self.Items.push(new ItemDetailViewModel(item));
});
}else{
// if there is no more data stop the interval function.
clearInterval(loadMoreTimer);
}
}
})
}
//Call to start lazy loading
self.AutomaticLoadItem();
}
var ItemDetailViewModel = function (data){
var self = this ;
self.Id = data.Id ;
self.Name = data.Name;
// .....
}