2015-04-03 2 views
2

Я использую нокаут для рендеринга большого количества данных. (35000 записей) Я не могу использовать запрос lazyload, передавая сервер, у меня есть данные в браузере.Нокаут медленно связывает огромное количество данных

Если я использую observableArray в моей модели ViewModel, браузер замораживается около 10 секунд, прежде чем показывать результат привязки.

var vm = function() { 
     var ar = []; 
     for (var i=0; i<35000; i++){ 
      ar.push(i); 
     } 
     this.SelectedElementsListData = ko.observableArray(ar); 
} 
ko.applyBindings(vm()); 

И с этим HTML связывания

<div data-bind="foreach:SelectedElementsListData" class="scrolling"> 
    <div data-bind="text:$data"></div> 
</div> 
<div data-bind="event: { click: fill }"> 
    CLICK HERE TO START 
</div> 

это прототип результата, необходимого

https://jsfiddle.net/RobertoSerafin/4axdwkfo/

Мой вопрос:

Как я могу сделать родовое customBinding, чтобы сделать foreach bindi ng более хитро и применить рендеринг только к частичному списку ArrayItems и использовать прокрутку div для рендеринга div только «onDemand», когда пользователь прокручивает div.

+0

попробуйте сделать ленивый образ в виде модели без доступа к серверу для данных прокрутки (на div). вы полностью против ленивой загрузки? .. –

+0

http://stackoverflow.com/questions/9709374/knockout-js-incredibly-slow-under-semi-large-datasets Я полагаю, что это причина, по которой ReactJS находится прямо сейчас, с ее виртуальным домиком, который кажется, сияет в этих ситуациях. –

ответ

1

Вы можете попробовать заменить место используемого обработчика привязки и попробовать https://github.com/brianmhunt/knockout-fast-foreach, но с этим количеством элементов я не думаю, что этого будет достаточно.

Вам понадобится либо пейджинг, либо виртуализированный список. Последнее - это то, что вы описали в своем последнем абзаце. При этом в качестве поискового термина достаточно легко найти решение.

1

Если не конкретное требование, что вы должны использовать привязку пользовательских нокаута, это, вероятно, проще использовать вычисленный наблюдаемым, чтобы дать вам кусочек исходного массива:

var vm = function() { 
    var source = []; 

    this.scroll = function() { 
     var objDiv = document.getElementById("scroll"); 
     objDiv.scrollTop = objDiv.scrollHeight;   
    } 

    this.visibleItems = ko.observable(50); 

    this.more = function() { 
     this.visibleItems(this.visibleItems() + 50); 
     this.scroll();   
    } 

    for (var i = 0; i < 50000; i++) { 
     source.push(i); 
    } 

    this.visible = ko.computed(function() { 
     return source.slice(0, this.visibleItems());    
    });   
} 

ko.applyBindings(vm()); 
this.scroll(); 

Example on JSFiddle

You может, с небольшой модификацией, использовать этот подход для реализации постраничного представления ваших данных. Это было бы намного лучше с точки зрения использования памяти, так как вы не добавили бы элементы в DOM, так как пользователь продолжает нажимать «Показать больше».

Смежные вопросы