Knockout.js 敲除DOM操作

Knockout.js 敲除DOM操作,knockout.js,Knockout.js,我想知道是否有一种方法可以减少knockoutjs的Dom操作——我有一个大的可观察数组,我看到在foreach中它需要分配一定的时间 在研究了代码并对其进行了调试之后,我发现knockout将所有元素放在dom中,而不是将所有元素放在一个位置 有没有一种快速的方法让knockout在foreach语句中创建一个包含所有子节点的长字符串,然后将该字符串写入DOM一次 我的代码: self.items = ko.observableArray([]); function generate

我想知道是否有一种方法可以减少knockoutjs的Dom操作——我有一个大的可观察数组,我看到在foreach中它需要分配一定的时间

在研究了代码并对其进行了调试之后,我发现knockout将所有元素放在dom中,而不是将所有元素放在一个位置

有没有一种快速的方法让knockout在foreach语句中创建一个包含所有子节点的长字符串,然后将该字符串写入DOM一次

我的代码:

self.items = ko.observableArray([]);     
function generateModel(data) {
            var mapped = $.map(data, function (d) { return new item(d); });
            self.items(mapped);
        }

<!--ko foreach:{data:items}-->
some template in here
<!--/ko-->
self.items=ko.observearray([]);
函数generateModel(数据){
var-mapped=$.map(数据,函数(d){返回新项(d);});
自我项目(映射);
}
这里有一些模板

谢谢。

是的,有一种使用油门扩展器的方法:如果您愿意,可以在这里找到一些好的提示:

更好的是,您可以在这里找到一个名为pauseableObservableArray(很棒的名字:)的定制对象的有趣实现,它来自一个巨大的开发人员:rpniemeyer)

除此之外,对于第一种简单的方法,您是否尝试使用
if
绑定从DOM中删除元素

例如。 html:


视图模型:

function BlogViewModel() {
    var self = this;
    self.blogs = ko.observableArray([{id:'qwe'}]);

    self.isWorking= ko.observable(false);


    self.populateBlogs = function () {
        self.isWorking(true);

        var tmp =  self.blogs();

        for (var i = 0; i < 100000; i++) {
            tmp.push({id:i});
        }


        self.blogs(tmp);
        self.isWorking(false);
    }


}
函数BlogViewModel(){
var self=这个;
self.blogs=ko.observearray([{id:'qwe'}]);
self.isWorking=ko.可观察(假);
self.populateBlogs=函数(){
self.isWorking(真);
var tmp=self.blogs();
对于(变量i=0;i<100000;i++){
tmp.push({id:i});
}
self.blogs(tmp);
self.isWorking(假);
}
}
[更新] 可能,如果您需要进一步改进渲染时间,您需要实现类似于我建议的中实现的内容,或者实现一个自定义绑定处理程序来“手动”完成所有操作。 例如,类似于:

html:


VIE模型:

ko.bindingHandlers.quickForEach = {

    update: function(element, valueAccessor, allBindingsAccessor, viewModel, bindingContext) {

        var blogs = valueAccessor()();
        var innerText='';
        for (var i = 0; i < blogs.length; i++) {
            //very dirty code!In production, concatenate strings in a smarter way
            innerText += blogs[i].id;
        }
        $(element).text(innerText);
    }
};
ko.bindingHandlers.quickForEach={
更新:函数(元素、valueAccessor、allBindingsAccessor、viewModel、bindingContext){
var blogs=valueAccessor();
var innerText='';
对于(var i=0;i
foreach绑定在呈现大型数组时效率不高。它的设计目的是有效地处理动态阵列(可以通过小的方式进行修改)

有几种解决方案可以帮助您:

  • 使用基于字符串的模板。安

  • 使用自定义绑定生成特定的HTML内容并将其添加到DOM中。这种技术的一个例子是我的

  • 使用更快的
    foreach
    风格的绑定,如my


  • 我不想延迟foreach语句(据我所知,throttle就是这么做的)——我不想让knockout将我在ObservalArray中的200个元素与200个附加到dom中,而只是在一个附加中。有多少项导致了这个问题?您真的需要呈现此页面上的所有项目吗?为什么不进行某种虚拟呈现?您好。谢谢你的回答。我正在寻找一种方法,保存一条巨大的字符串,然后只将其添加到dom中一次。在我的网站上,我看到了与大型数组的竞争——我通过从服务器分页来减少该数组,但您仍然会看到有时渲染需要很长时间。感谢您的回答在knockout中是否有使用多个模板引擎的方法?我已经更新了下划线示例以使用
    templateEngine
    选项,该选项支持以下内容:我将看看Michael的最佳建议,并按照您在更新中的建议使用基于字符串的模板。感谢您提供的有关ifnot方法的提示-这将渲染提高了两倍。
    <div data-bind="quickForEach: blogs"></div>
    
    ko.bindingHandlers.quickForEach = {
    
        update: function(element, valueAccessor, allBindingsAccessor, viewModel, bindingContext) {
    
            var blogs = valueAccessor()();
            var innerText='';
            for (var i = 0; i < blogs.length; i++) {
                //very dirty code!In production, concatenate strings in a smarter way
                innerText += blogs[i].id;
            }
            $(element).text(innerText);
        }
    };