【问题标题】:Implementing Knockout.js destructive foreach loop实现 Knockout.js 破坏性 foreach 循环
【发布时间】:2016-10-12 17:35:07
【问题描述】:

这是带有数据绑定元素的 html:

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 调用,会返回不同的 requestArray。例如,在初始页面加载后,进行了一个 AJAX 调用,该调用接收一个可能有 10 个项目的 requestArray 实例。 foreach 循环似乎按预期运行,数组中的所有 10 个项目都填充在页面上。然后,进行第二次 AJAX 调用,但这次数组可能只有 5 个项目。发生的情况是每个项目重复两次,页面上总共出现 10 个项目。

问题似乎在于,即使之前调用了ko.cleanNode(document.getElementById('test2'))

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

对于每个新数组,每个 foreach 迭代创建的 HTML 元素的数量随着每个新数组的增加而不断增加。使用 Vue.js,每次将新数组传递给数据绑定和 for 循环时,它本质上都是破坏性的,并且不会保留数组上一次迭代的任何内容。

显然在这种情况下使用ko.cleanNode 在这里不起作用,我知道in the docs 有一个示例可以执行我认为正确的过程,但一次只能通过一个按钮和一个html 元素self.array.remove(this),我不太确定如何调整它以完全清除从数组 foreach 迭代创建的所有 html 元素。

【问题讨论】:

  • 为什么每次调用 Ajax 时不清空模型中的数组?1
  • @Matt.kaaj 我正在这样做,将在帖子中更新我的代码。它对 Knockout.js 绑定的情况没有帮助。更新数组本身不是问题,它是通过每个新数组每次 foreach 迭代创建的 html 元素的累积。

标签: javascript arrays knockout.js


【解决方案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>

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-05-10
    • 1970-01-01
    • 1970-01-01
    • 2012-02-16
    • 1970-01-01
    • 2019-03-21
    相关资源
    最近更新 更多