2016-10-12 4 views
1

Вот HTML с элементами данных связывания:Реализация Knockout.js разрушительный Еогеасп петля

div data-bind="foreach: clientRequests" id="test2"> 
      <div class="list-group" > 
       <a href="#" class="list-group-item active"><b data-bind="text: client"></b></a> 
       <a href="#" class="list-group-item"><b>Priority: </b><b data-bind="text: client_priority"></b></a> 
       <a href="#" class="list-group-item"><b>Title: </b><b data-bind="text: title"></b></a> 
       <a href="#" class="list-group-item"><b>Description: </b><b data-bind="text: description"></b></a> 
       <a href="#" class="list-group-item"><b>Product Area: </b><b data-bind="text: product_area"></b></a> 
       <a href="#" class="list-group-item"><b>Target Date: </b><b data-bind="text: target_date"></b></a> 
       <a href="#" class="list-group-item"><b>Ticket URL: </b><b data-bind="text: ticket_url"></b></a> 
      </div> 
     </div> 

Это, как я передаю массив называется requestsArray к foreach цикла:

ko.cleanNode(document.getElementById('test2')); 

     ko.applyBindings({ 
      clientRequests: requestsArray 
     }, document.getElementById('test2')); 

При различных вызовах AJAX возвращаются разные requestArrays. Например, после загрузки начальной страницы выполняется вызов AJAX, который получает один экземпляр requestArray, который может содержать 10 элементов. Кажется, что цикл foreach ведет себя так, как ожидалось, и все 10 элементов в массиве заполняются на странице. Затем выполняется второй вызов AJAX, но на этот раз в массиве может быть только 5 элементов. Случается, что каждый элемент повторяется дважды, и на странице появляется всего 10 элементов.

Проблема, кажется, что, несмотря на то, ko.cleanNode(document.getElementById('test2')) вызывается до:

ko.applyBindings({ 
       clientRequests: requestsArray 
      }, document.getElementById('test2')) 

с каждым новым массивом, число элементов HTML, создаваемых каждой итерации foreach продолжает увеличиваться с каждым новым массивом. С Vue.js каждый раз, когда вы передаете новый массив привязке данных и для цикла, он разрушительный по своей природе и ничего не сохраняет от предыдущей итерации по массиву.

Очевидно, используя ko.cleanNode здесь не работает в этом сценарии, и я знаю in the docs есть пример, который делает то, что я думаю, что это правильная процедура, но только один HTML элемент, в то время с помощью кнопки и self.array.remove(this) и Я не совсем уверен, как его адаптировать, чтобы выполнить полную очистку всех элементов html, созданных из массива foreach итерации.

+0

почему вы не опустошить ваш массив в модели каждый раз, когда вы называете Ajax? 1 –

+0

@ Matt.kaaj Я делаю, что будет обновлять свой код в пост. Это не помогает в том, что происходит с привязкой Knockout.js. Обновление самого массива не является проблемой, это накопление элементов html, созданных с каждой итерацией foreach через каждый новый массив. – AdjunctProfessorFalcon

ответ

1

Я не понимаю, почему вам придется повторно применять привязки вручную. Вся точка зрения модели с наблюдаемым массивом состоит в том, что нокаут заботится о обновлениях данных для вас ... Обычно, когда вы используете cleanNode, есть более простой способ сделать что-то.

Вы пробовали что-то вроде этого?

// Apply bindings _once_, viewmodel instance does not change 
 
// in between requests 
 
ko.applyBindings(new ViewModel()); 
 

 

 
function ViewModel() { 
 
    // Because the array is observable, knockout will 
 
    // monitor for changes and update the UI 
 
    this.requests = ko.observableArray([]); 
 
    
 
    // The view model has the request method 
 
    // the .done callback writes the results to the observable 
 
    // requests array 
 
    this.doRequest = function() { 
 
    mockupAjaxGetter().done(this.requests); 
 
    }.bind(this); 
 
    
 
    // Do an initial request 
 
    this.doRequest(); 
 
}; 
 

 

 

 
// Mockup code, just to produce some random numbers on a timeout 
 
function mockupAjaxGetter() { 
 
    var randomResults = []; 
 
    for (var i = 0; i < Math.random() * 20; i += 1) { 
 
    randomResults.push(Math.random()); 
 
    } 
 
    var cb; 
 
    var applyCb = function() { 
 
    if (cb) cb(randomResults); 
 
    } 
 
    
 
    setTimeout(applyCb, 500); 
 
    
 
    return { 
 
    done: function(fn) { cb = fn; } 
 
    } 
 
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.2.0/knockout-min.js"></script> 
 

 
<ul data-bind="foreach: requests"> 
 
    <li data-bind="text: $data"></li> 
 
</ul> 
 
<button data-bind="click: doRequest">New request</button>

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