2

ノックアウトでfadeIn()fadeOut()などのjqueryアニメーションを使用しようとすると、いくつかの課題に直面しています。

アニメーションなしの実際の例: http://jsfiddle.net/LkqTU/23801/

計算されたオブザーバブルを使用して、元の慈善団体の配列をフィルター処理します。計算されたものはforeachでデータバインドされており、コンテナ全体(クラス.tabを使用)を変更前にフェードアウトさせ、変更後にフェードインさせたいと考えています。

組み込みの beforeRemove および afterAdd プロパティを使用してみましたが、配列が計算されるときに機能しないようです。以下のライブの例に見られるように、コンテナはいくつかの慈善団体のいくつかのインスタンスによって満たされますが、基礎となる計算された配列には正しいものしか含まれていません。

(失敗した) アニメーションを含む実際の例: http://jsfiddle.net/fy7au6x6/1/

アニメーションで計算されたものへの変更のタイミングを制御する方法について何か提案はありますか?

これらは、「すべての慈善団体」と「カテゴリ別にフィルタリングされた慈善団体」の 2 つの配列です。

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.computed(function () {

    // If no category is selected, return all charities
    if (!self.selectedCategory())
        return self.allCharities();

    // Return charities in the selected category
    return ko.utils.arrayFilter(self.allCharities(), function (c) {
        return (c.Category() == self.selectedCategory());
    });

}, this);
4

2 に答える 2

1

カスタムバインディングハンドラーを使用した、よりクリーンな回答を次に示します。

秘訣は、本質的に「私は変わろうとしている」という 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();
于 2015-04-20T19:09:01.427 に答える