2016-08-25 79 views
0

我正在使用分頁的foreach向用戶顯示通知列表。現在我想知道該項目是否在屏幕上顯示給用戶足夠的時間來將通知狀態從新建更新爲已查看。我無法將它更新到所有呈現的項目,因爲我使用的分頁也可能不會顯示某些項目,因此我想在顯示足夠的時間後將其標記爲已更新(例如5秒)有什麼方法可以跟蹤Knockout Observable Array項目是否顯示在UI中?

回答

1

基因敲除具有非常方便您可以使用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

相關問題