有什么方法可以跟踪Knockout Observable Array项目是否显示在UI中?

问题描述:

我正在使用分页的foreach向用户显示通知列表。现在我想知道该项目是否在屏幕上显示给用户足够的时间来将通知状态从新建更新为已查看。我无法将它更新到所有呈现的项目,因为我使用的分页也可能不会显示某些项目,因此我想在显示足够的时间后将其标记为已更新(例如5秒)有什么方法可以跟踪Knockout Observable Array项目是否显示在UI中?

基因敲除具有非常方便您可以使用rateLimit扩展名执行延迟更新。通过创建当前页面observable的计算副本,并将其扩展为仅在停止更改后5秒钟通知您,则可以将该页面上的项目更新为read状态。例如:

var delayedPage = ko.computed(function() { 
    // Loop through the items that are rendered (a computed of `page`) 
    // Note: this makes the computed impure 
    itemsOnDisplay().forEach(function(item) { 
    // Set an observable status property of their viewmodel 
    item.read(true); 
    }); 

    // This creates the subscription to page changes 
    return page(); 
}, this).extend({ 
    rateLimit: { 
    timeout: 5000, 
    method: "notifyWhenChangesStop" 
    } 
}); 

在工作示例:

  • 物品的集合与布尔read观察到
  • 可观察page属性,它告诉我们,我们是在
  • 一个什么网页计算出的一组itemsOnDisplay,其中包含当前呈现的项目
  • 当前页面的更新率限制反映最后一页变化

var ViewModel = function(data) { 
 
    this.itemsPerPage = 6; 
 
    this.page = ko.observable(); 
 
    this.items = ko.observableArray(data); 
 
    
 
    
 
    this.displayItems = ko.pureComputed(function() { 
 
    var start = this.page() * this.itemsPerPage; 
 
    var end = start + this.itemsPerPage; 
 
    return this.items().slice(start, end); 
 
    }, this); 
 
    
 
    this.canGoBack = ko.pureComputed(function() { 
 
    return this.page() > 0; 
 
    }, this); 
 
    
 
    this.canGoForward = ko.pureComputed(function() { 
 
    return (this.page() + 1) * this.itemsPerPage < this.items().length; 
 
    }, this); 
 
    
 
    // The important part: 
 
    this.delayedPage = ko.computed(function() { 
 
    var currentPage = this.page(); 
 
    if (typeof currentPage === "undefined") return null; 
 
    
 
    this.displayItems().forEach(function(item) { 
 
     item.read(true); 
 
    }); 
 
    
 
    console.log("Read items on page " + currentPage); 
 
    return currentPage; 
 
    }, this).extend({ rateLimit: { timeout: 5000, method: "notifyWhenChangesStop" } }); 
 
    
 
    this.page(0); 
 
    
 
} 
 

 
ViewModel.prototype.prev = function() { 
 
    this.page(Math.max(this.page() - 1, 0)); 
 
}; 
 

 
      
 
ViewModel.prototype.next = function() { 
 
    this.page(Math.min(this.page() + 1, Math.ceil(this.items().length/this.itemsPerPage))); 
 
}; 
 

 
      
 
      
 
      
 
var myData = []; 
 
for (var i = 0; i < 50; i += 1) { 
 
    myData.push({ 
 
    label: "Item " + i, 
 
    read: ko.observable(false) 
 
    }); 
 
} 
 

 
var vm = new ViewModel(myData); 
 

 
ko.applyBindings(vm);
li::after { 
 
    content: "new"; 
 
    font-style: italic; 
 
    margin-left: 1rem; 
 
    padding: .25rem; 
 
    background: orange; 
 
} 
 

 
.is-read { 
 
    background: #efefef; 
 
} 
 

 
.is-read::after { 
 
    display: none; 
 
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.2.0/knockout-min.js"></script> 
 
<ul data-bind="foreach: displayItems"> 
 
    <li data-bind="text: label, css: {'is-read': read }"></li> 
 
</ul> 
 

 
<button data-bind="click: prev, enable: canGoBack">prev</button> 
 
<button data-bind="click: next, enable: canGoForward">next</button>

+0

这到底是什么我期待的后TES 5秒。 – Nishanthan