1

コンストラクター関数によって作成されたビューモデルがあり、一連の監視可能なプロパティと一連のプレーンな古いプロパティがあります。インスタンス化したら、インスタンスに値を設定すると、その値への変更は計算されたオブザーバブルに反映されません。

これが私が見ているものの蒸留版です:

function ViewModel(active) {
    var self = this;
    self.active = active;

    self.getClasses = ko.computed(function () {
        return this.active ? "yup" : "nope";
    }, self);
}

var vm = new ViewModel(false);
vm.active = true;

alert(vm.getClasses()); //returns "nope" :/

この計算されたオブザーバブルは、依存するオブザーバブルに触れると再評価されますが、直接呼び出すと、アクティブの古い値で評価されます。

ko.computed は、親への更新を無視する新しいクロージャーを作成しますか? プレーンな値と観察可能な値を混在させることはお勧めできませんか? (私が実際に問題を抱えている計算には、オブザーバブルや他のプロパティへの依存関係がありますが、実行時に他のプロパティが変更されるとは思いません。これは、実際には現在の単体テストの問題です。)

確かにアクティブをオブザーバブルにすることはできますが、これを行う別の方法があるかどうか疑問に思っています。

4

3 に答える 3

3

Josh、内部では ko.computed が計算関数をすぐに実行し、なんらかのアクションで再計算が必要になるまで結果を保存します (サブスクライブされたオブザーバブルの変更など)。この内部キャッシングにより、パフォーマンスが大幅に向上する可能性があります。サブスクライブ先の値が変更されていない場合は、結果が同じになるはずなので、計算を再実行する必要はありません。

これが、計算が依存する値をオブザーバブルとして作成することが重要な理由です。

通常、これはアーキテクチャに問題があることを示しているため、computed を強制的にオンデマンドで再計算する方法はありません。オンデマンドで計算されるが、オブザーバブルに依存しない値が必要な場合は、通常の関数がそれを達成するための最良の方法です。

self.getClasses = function () {
      return self.active() ? "yup" : "nope";
  };

UI をバインドして、通常の関数の結果を計算結果とまったく同じように表示できますが、バインド式に括弧を追加する必要があります。これは、バインド時の関数の結果のみを表示することに注意してください。計算が変更されると、UI は最新の状態に保たれません。そのためには、ko.computed が必要です。

<!-- this will only show the value at bind-time and never be updated -->
<div data-bind="text: getClasses()"></div>

ご覧のとおり、これはあまり役に立ちません。全体として、いくつかのオブザーバブルがアプリのパフォーマンスに数マイクロ秒以上影響を与える可能性は低いです。問題が発生するまで、コードの最適化を保留することをお勧めします。ユーザーは、コードの記述を容易にするいくつかのオブザーバブルよりも、ループ評価または大きな AJAX ペイロードで速度低下を感じる可能性がはるかに高くなります。

これが役立つことを願っています!

于 2013-07-17T01:51:25.097 に答える
1

次のように観察可能な値を設定しようとしましたか:

function ViewModel(active) {
  var self = this;

  self.active = ko.observable(active);

  self.getClasses = ko.computed(function () {
      return this.active() ? "yup" : "nope";
  }, self);
}

var vm = new ViewModel(false);
vm.active(true);

そのため、オブザーバブルをプロパティとしてではなく、(括弧内の値を使用して) 関数として設定します。activeそして、それがオブザーバブルとして定義されていることを確認します。

于 2013-07-16T20:38:55.843 に答える