カスタムバインディングハンドラーを使用した、よりクリーンな回答を次に示します。
秘訣は、本質的に「私は変わろうとしている」という 1 つのブール値を使用することです...これを true に設定すると、単純なバインディング ハンドラーでフェードアウトします。
フィルターが処理されて準備ができたら、同じブール値を false に設定します。これは、本質的には「完了しました」という意味です...それが発生すると、小さなハンドラーがフェードインします。
秘訣は、計算された配列の代わりに、サブスクリプションと 2 番目の監視可能な配列を使用することです。これにより、ブール値をtrueに設定し、2番目のオブザーバブルを埋めてから、そのオブザーバブルをfalseに設定できます...これにより、バインディング動作のタイミングを気にすることなく、フェードイン、フェードアウト動作を駆動できます。
フィドル:
http://jsfiddle.net/brettwgreen/h9m5wb8k/
HTML:
<div class="side-bar">
<a href="#" class="category" data-bind="click: function(){ setCategory('')}">All</a>
<a href="#" class="category" data-bind="click: function(){ setCategory('EDUCATION')}">Education</a>
<a href="#" class="category" data-bind="click: function(){ setCategory('HUMANITARIAN')}">Humanitarian</a>
</div>
<div class="tab" data-bind="fader: filtering, foreach: filteredCharities">
<div class="tab-tile mb21" data-bind="css:{'mr21':$index()%3 < 2}">
<a href="#" class="amount" data-bind="text: Amount"></a>
<a href="#" class="title" data-bind="text: Name"></a>
<a href="#" class="category" data-bind="text: Category"></a>
</div>
</div>
JS:
ko.bindingHandlers.fader = {
update: function(element, valueAccessor) {
var obs = valueAccessor();
var val = ko.unwrap(obs);
if (val) {
$(element).fadeOut(500);
}
else
{
$(element).fadeIn(500);
}
}
};
function Charity(id, name, amount, category) {
var self = this;
self.Id = ko.observable(id);
self.Name = ko.observable(name);
self.Amount = ko.observable(amount);
self.Category = ko.observable(category);
}
// ----------------------------------------------------------
// VIEWMODEL ------------------------------------------------
// ----------------------------------------------------------
function ViewModel() {
var self = this;
self.selectedCategory = ko.observable("");
self.filtering = ko.observable(false);
self.setCategory = function (newCat) {
self.filtering(true);
window.setTimeout(function() {self.selectedCategory(newCat);}, 500);
};
self.allCharities = ko.observableArray([
new Charity(0, "Amnesty International", "$2,466", "HUMANITARIAN"),
new Charity(1, "Richard Dawkins Foundation", "$0", "EDUCATION"),
new Charity(2, "Khaaaan Academy", "13,859", "EDUCATION"),
new Charity(4, "Wikipedia", "$7,239", "EDUCATION")
]);
self.filteredCharities = ko.observableArray(self.allCharities());
self.selectedCategory.subscribe(function(newValue) {
self.filtering(true);
console.log(newValue);
if (!newValue)
self.filteredCharities(self.allCharities());
else {
var fChars = ko.utils.arrayFilter(self.allCharities(), function (c) {
return (c.Category() === newValue);
});
self.filteredCharities(fChars);
};
self.filtering(false);
});
};
// ----------------------------------------------------------
// DOCUMENT READY FUNCTION ----------------------------------
// ----------------------------------------------------------
$(document).ready(function () {
ko.applyBindings(vm);
});
var vm = new ViewModel();