「with」バインディングを使用していますが、値を変更する前とその後にアニメーションを呼び出したいと思います。誰かがそれを行う方法を知っていますか?
3 に答える
次のようなアニメーションにjQueryを使用する独自のバインディングで、いつでもwithバインディングをラップできます。
ko.bindingHandlers['fadingWith'] = {
init: function(element, valueAccessor, allBindingsAccessor, context) {
return ko.bindingHandlers['with']['init'](element, valueAccessor, allBindingsAccessor, context);
},
update: function(element, valueAccessor, allBindingsAccessor, context) {
$(element).fadeOut(100, function () {
ko.bindingHandlers['with']['update'](element, valueAccessor, allBindingsAccessor, context)
}).fadeIn(100);
}
};
ko.virtualElements.allowedBindings['fadingWith'] = true;
次に、次のように適用できます。<div data-bind="fadingWith: someObservable"><span data-bind="text: $data"></span></div>
私はこれをテストしていません(後で試してみます)が、これが進むべき方向だと思います。
別のオプション(私はもっと確実に機能するでしょう)は、次のことを行う別のバインディングを作成することです。
ko.bindingHandlers['fadeOn'] = {
update: function(element) {
$(element).hide().fadeIn(200);
}
}
それは、観察可能な変化の前のアニメーションを提供しませんが、その後のアニメーションを提供します。だからあなたはするだろう<div data-bind="with: someObservable, fadeOn: someObservable"><span data-bind="text: $data"></span></div>
編集:私が今思いついたもう1つのおそらくより簡単なwith
オプションは、使用している変数でスロットル拡張を使用することです:
ViewModel:
///...your code....
this.observableThatNeedsWith = ko.observable("Hello");
this.delayedObservable = ko.computed(this.observableThatNeedsWith).extend({throttle: 200});
//...continue your code
次に、次のようなバインディングがあります。
ko.bindingHandlers['fadeInOut'] = {
update: function(element) {
$(element).stop(true, true).stop(true, true).fadeOut(200).fadeIn(200);
}
}
フェードアウト時間はスロットル時間と同じであることに注意してください。
次に、次のようにバインドします。<div data-bind="with: delayedObservable, fadeInOut: observableThatNeedsWith"><span data-bind="text: $data"></span></div>
observableThatNeedsWithを変更すると、fadeInOutハンドラーが要素の遷移を開始します。次に、フェードアウトが完了した瞬間(この場合は200ms)にスロットルが追いつき、fadeInOutが要素をフェードインし始めるとすぐにdelayedObservableが更新されます。あるものがフェードアウトし、別のものがフェードインします。
要素のコピーを作成するバインディングを作成することで問題を解決しました。この要素のクローンを作成した後、それをアニメーション化し、その後、それを削除して、元の要素を新しい値でアニメーション化します。このバインディングを前に設定することが重要です
Los Frijolesの3番目のソリューションは、アニメーションの後に常に行われるように「with」バインディングを調整するため、機能しません。
withバインディングによってレンダリングされた要素をアニメーション化しようとしているため、レンダリングされていない状態からレンダリングされた状態に移行するときに、アニメーションは存在しない要素をアニメーション化しようとします。
Slawomirの答えは私が見た中で最高ですが、モバイルデバイスでアニメーション化するときに複雑な要素のクローンを作成することは、パフォーマンス上の理由からオプションではありません。これらのバインディングのアニメーションを適切に実装するには、Knockoutフレームワークを改善する必要があります。
編集:同等のロジックの「template」または「foreach」タグに置き換えることで、「with」または「if」バインディングをアニメーション化できることに気付きました。たとえば、私は置き換えました:
<div data-bind="with: selectedTimelapse">
と:
<div data-bind="template: {
foreach: selectedTimelapse,
afterAdd: utils.kbAnimFadeIn,
beforeRemove: utils.kbAnimFadeOut
}">
私の例の「selectedTimelapse」がリストである必要はありません。これを使用して、selectedTimelapseが設定されているときに、モーダルダイアログを出入りできるようになりました。この手法は、遷移の場合にも機能するようにハッキングされる可能性があります。
<div data-bind="template: {
foreach: (showTimelapse()) ? selectedTimelapse : undefined,
afterAdd: utils.kbAnimFadeIn,
beforeRemove: utils.kbAnimFadeOut
}">
私のutils.kbAnimFadeIn/Out関数は、次のKnockoutアニメーションの例のページに示されている関数と同等です: http: //knockoutjs.com/examples/animatedTransitions.html