我使用foreach with pagination向用户显示通知列表。现在,我想知道是否在屏幕上为用户显示该项目的时间足以将通知状态从“新建”更新为“已查看”。我无法将其更新为所有渲染的项目,因为我使用分页时可能无法显示某些项目,我也希望在显示足够的时间后将其标记为已更新(例如5秒)
答案 0 :(得分:1)
Knockout有一个非常方便的rateLimit
扩展程序,可用于执行延迟更新。通过创建当前页面的可观察计算副本,并将其扩展为仅在停止更改后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);
&#13;
li::after {
content: "new";
font-style: italic;
margin-left: 1rem;
padding: .25rem;
background: orange;
}
.is-read {
background: #efefef;
}
.is-read::after {
display: none;
}
&#13;
<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>
&#13;