2016-08-25 14 views
0

私は、通知リストをユーザーに表示するためにページ分割を使ってforeachを使用しています。ここでは、通知ステータスをNewからViewedに更新するのに十分な時間、アイテムがユーザーの画面に表示されているかどうかを確認したいと思います。私はページネーションを使用しているのでアイテムのいくつかが表示されない可能性があるので、レンダリングされたすべてのアイテムに更新することはできません。十分な時間(例えば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" 
    } 
}); 

  • 我々は
  • Aにしているどのようなページを教えてくれるブールread
  • 観測可能な観測可能 pageプロパティを持つアイテムのコレクション現在レンダリングされているアイテムを保持する itemsOnDisplayの計算済みセット
  • 現在のページのレート制限が反映されているupda TES最後のページの変更後5秒

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

これは私が期待していたまさにです。 – Nishanthan

関連する問題