なぜ私のknockoutjsカスタムバインディングがトリガーされているのですか?
-
26-10-2019 - |
質問
奇妙な状況があります。基本的に、DOM要素を新しい値にアニメーション化するために使用される2つのカスタムバインディングがあります。これらは、それぞれ幅と正しい値をアニメーション化するAwidthとArightです。
このようなバインディングを実装しました:
<div class='classname' data-bind="aRight: right, aWidth: containerWidth, style: { zIndex: zindex, left: (left() + 'px'), height: (containerHeight() + 'px') }">
...そしてカスタムバインディングは次のようになります:
ko.bindingHandlers.aWidth =
{
update: function (element, valueAccessor, allBindingsAccessor, context)
{
// Get the value accessor
var value = valueAccessor();
// Get the new width and the duration of the animation
var newWidth = ko.utils.unwrapObservable(value);
var duration = 500;
$(element).animate({ width: newWidth }, duration, "swing");
}
};
ko.bindingHandlers.aRight =
{
update: function (element, valueAccessor, allBindingsAccessor, context)
{
// Get the value accessor
var value = valueAccessor();
// Get the new width and the duration of the animation
var newRight = ko.utils.unwrapObservable(value);
var duration = 500;
$(element).animate({ right: newRight }, duration, "swing");
console.log("aRight Called: newRight - " + newRight + ", duration - " + duration);
}
};
したがって、問題は、たとえばZindexなど、2つのカスタムバインドされた観測可能性以外の観測可能なものを変更すると、問題が発生します。
観測可能なZindexを変更すると、値はDOMで正しく更新されますが、何らかの理由で、私のAright Bindingもトリガーされます!...
私は私の無地のカスタムバインディングにそれを参照していないので、確かに依存関係はありませんか?
Awidth Bindingがトリガーされると、私のARight Bindingもトリガーされますが、これも少し奇妙です!
誰かがこれについて何かアイデアを持っていますか?
どうもありがとう!
アンディ。
アップデート
これは、インデックスを更新するViewモデルの一部であり、私のAright Custom Bindingに火災に引き起こされると(これは非常にPSUDOコードです!):
var page = function()
{
this.zindex = ko.observable(0);
this.right = ko.observable(0);
// and other observables....
}
var viewModel = function()
{
var pages = ko.oberservableArray();
// populate the pages array etc...
this.someMethod = function()
{
// Do some stuff...
this.anotherMethod();
// Do some other stuff
}
.bind(this);
this.anotherMethod() = function
{
var pageCount = this.pages().length;
for (var pageNum = 0; pageNum < pageCount; pageNum++)
{
var page = this.pages()[pageNum];
page.zindex(/* a different value */); // This is what causes my aRight binding to fire...
}
}
.bind(this);
}
アップデート
言う:
さらに、同じデータバインド属性の別のバインディングがトリガーされた場合、バインディングは再び更新機能を実行します。
これは、私が見ているのは、私のカスタムバインディングが他のバインディングがデータバインド属性をトリガーしたときにトリガーされていることを意味します(Zindexが最初に変化するのはおそらく起こるかもしれません)?これは少し奇妙な/間違っていませんか?...
アップデート
私は私の問題をほぼまとめていると思うシンプルなフィドルを持っています。同じデータバインド属性のバインディングは、多くのカスタムバインディングが更新されるようになるようです!
うーん...値が実際に変更されたかどうかについてカスタムバインディングを手動でチェックすることで、私はそれを回避しなければならないと思います!!これはバインディングの実際のポイントを打ち負かさないのですか?
また、ノックアウトフォーラムにもっと正確な質問を投稿しました。 http://groups.google.com/group/knockoutjs/browse_thread/thread/d2290d96e33f1d5a
解決
これは現在設計によるものです。データバインド内のすべてのバインディングは、バインディングのいずれかの火災の場合にトリガーされます。これは、それらがすべて単一の依存装置に包まれているためです。場合によっては、バインディングは互いに依存関係があります(オプションが更新された場合、それがまだ有効な値であることを確認するために値を実行する必要があります)。ただし、場合によっては、これは問題を引き起こします。
この動作を軽減するのに役立つカスタムバインディングを作成するときに使用できる別のパターンがあります。 「更新」関数で機能の勇気を定義する代わりに、実際に「init」関数で独自の依存関係を作成します。それは次のようになります:
ko.bindingHandlers.custBinding= {
init: function(element, valueAccessor) {
ko.dependentObservable({
read: function() {
ko.utils.unwrapObservable(valueAccessor());
alert("custBinding triggered");
},
disposeWhenNodeIsRemoved: element
});
}
};