2016-10-25 15 views
4

これは特に技術的な質問ではありませんが、このような問題に対する最善のアプローチは何か不思議です。ノックアウトでこの問題が発生しても、ユースケースは他の場所でも有効であると確信しています。複数のサブスクライブされた変数が一緒に呼び出されたときに関数を1回だけ呼び出す方法

2つの変数simpleObserve1simpleObserve2を購読しているので、値が変更されるたびに関数resetAllValues()が呼び出されます。

var simpleObserve1 = ko.observable(0), // initial values 
    simpleObserve2 = ko.observable(0); // initial values 

var resetAllValues = function resetAllValues() { 
    /* this function takes all observable values and resets them */ 
    {...} 
} 

simpleObserve1.subscribe(function(){ 
    resetAllValues(); 
}); 

simpleObserve2.subscribe(function(){ 
    resetAllValues(); 
}); 

simpleObserve1(5); // value changed anywhere in code 
simpleObserve2(10); // value changed anywhere in code 

ここに2つの質問があります。 resetAllValues()が呼び出されると

  1. は、simpleObserve1simpleObserve2含む0に対するすべての加入の値を変更します。これはまた、resetAllValues()を何度も呼び出します。これが無限ループにならないようにするにはどうすればよいですか?
  2. 両方の変数を一緒に更新したいが、resetAllValues()を1回だけ呼び出す場合はどうすればよいですか?

私は助けにknockout's dispose()メソッドを使用しようとしましたが、これを行うより良い方法があるかどうか疑問に思っていました。

答えて

0

高次関数acceptXParamsを作成しました。これは、パラメータの数が​​または任意の数に等しいかどうかを確認します。ない場合は、元の関数が呼び出されることはありません。

function acceptXParams(fn, numOfParams) { 
 
    var numOfParams = numOfParams === undefined ? fn.length : numOfParams; 
 
    
 
    return function() { 
 
    if(arguments.length !== numOfParams) { 
 
     return; 
 
    } 
 
    
 
    return fn.apply(fn, arguments); 
 
    } 
 
} 
 

 
/** example **/ 
 

 
function sum(a, b, c) { 
 
    return a + b + c; 
 
} 
 

 
var sum3 = acceptXParams(sum); 
 

 
console.log(sum3(1, 2, 3)); 
 

 
console.log(sum3(1, 2)); 
 

 
console.log(sum3(1, 2, 3, 4));

そして、もっと洗練さES6バージョンacceptXParams

const acceptXParams = (fn, numOfParams = fn.length) => 
    (...args) => 
     args.length === numOfParams ? fn(...args) : undefined; 
1

Deferred Updatesはあなたを助けるかもしれません。計算されたノックアウトで観測値の値を使うことで、サブスクリプションが作成されます。これを拡張することによって、急速に変化する変化がある種のマイクロタスクで結合されます。

これらはループの動作を防止しますが、トリガされる更新の数は不明です。すなわち、5および10に設定すると、または計算結果が得られます。これがあなたの質問に答えるかどうかは完全にはわかりません。

var i = 0, 
 
    simpleObserve1 = ko.observable(0), // initial values 
 
    simpleObserve2 = ko.observable(0); // initial values 
 

 
ko.computed(function resetAllValues() { 
 
    console.log("Set " + ++i + ", before:"); 
 
    console.log("1: ", simpleObserve1()); 
 
    console.log("2: ", simpleObserve2()); 
 

 
    simpleObserve1(0); 
 
    simpleObserve2(0); 
 

 
    console.log("Set " + i + ", after:"); 
 
    console.log("1: ", simpleObserve1()); 
 
    console.log("2: ", simpleObserve2()); 
 

 
}).extend({ 
 
    deferred: true 
 
}); 
 

 
simpleObserve1(5); // value changed anywhere in code 
 
simpleObserve2(10); // value changed anywhere in code
.as-console-wrapper { min-height: 100%; } 
 
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.2.0/knockout-min.js"></script>

関連する問題