17

計算されたオブザーバブル(後でprotectedObservableに変換します)でCookieをラップしようとしていますが、計算されたオブザーバブルに問題があります。計算されたオブザーバブルへの変更は、それにバインドされているすべてのUI要素にブロードキャストされると私は考えていました。

私は次のフィドルを作成しました

JavaScript

var viewModel = {};

// simulating a cookie store, this part isnt as important
var cookie = function () {  

    // simulating a value stored in cookies
    var privateZipcode = "12345";

    return {
        'write' : function (val) { privateZipcode = val; }, 
        'read': function () { return privateZipcode; }
    }
}();

viewModel.zipcode = ko.computed({
        read: function () {
            return cookie.read();
        },
        write: function (value) {
            cookie.write(value);
        },
        owner: viewModel
    });

ko.applyBindings(viewModel);?

HTML

zipcode:
<input type='text' data-bind="value: zipcode"> <br />

zipcode: 
<span data-bind="text: zipcode"></span>?

オブザーバブルを使用して保存することはありませんprivateZipcode。これは、実際にはCookieに含まれるためです。私が見た例のほとんどはカバーの下を使用することko.computedになりますが、が必要な通知とバインディング機能を提供することを望んでいます。ko.computedko.observable

計算されたオブザーバブルに値を書き込むという行為は、その値にバインドされているUI要素に信号を送るべきではありませんか?これらはただ更新するべきではありませんか?

回避策

簡単な回避策がありko.observableます。Cookieストアと一緒に使用すると、DOM要素に必要な更新がトリガーされますがko.computed、シグナリング/依存関係タイプの機能がない場合を除いて、これは完全に不要のようko.observableです。

私の回避策のフィドルですが、変更されるのは、ストアとして使用されていないを追加したseperateObservableことだけです。その唯一の目的は、基になるデータが変更されたことをUIに通知することです。

// simulating a cookie store, this part isnt as important
var cookie = function () {  

    // simulating a value stored in cookies
    var privateZipcode = "12345";

    // extra observable that isnt really used as a store, just to trigger updates to the UI
    var seperateObservable = ko.observable(privateZipcode);

    return {
        'write' : function (val) { 
            privateZipcode = val; 
            seperateObservable(val);
        }, 
        'read': function () { 
            seperateObservable();
            return privateZipcode; 
        }
    }
}();

これは理にかなっており、私が期待するとおりに機能します。これは、UIにviewModel.zipcode依存しseperateObservableて更新することで、UIに更新を通知する必要があるためです。 私が理解していないのは、その要素がそれにバインドされているので、なぜwrite私のシグナルの関数を呼び出してko.computedUIを更新しないのko.computedですか?

ノックアウトで何かを使用して、自分ko.computedが更新されたことを手動で通知する必要があるのではないかと思ったのですが、それで問題ありません。それは理にかなっています。私はそれを達成する方法を見つけることができませんでした。

4

2 に答える 2

18

ため息、まったく同じ問題を抱えている人を見つけました

dependentObservablesが書き込み時にSubscribersに通知しない場合、なぜ読み取り時にわざわざ通知するのでしょうか。それらはオブザーバブルリストに追加されてサブスクライブされますが、更新時にトリガーされることはありません。では、それらをサブスクライブすることのポイントは何ですか?

ライアン・ニーマイヤーは答えます:

あなたのシナリオでは、dependentObservablesはその仕事に適したツールではないかもしれないと思います。dependentObservablesは、読み取り関数の依存関係を検出し、それらの依存関係のいずれかが変更されるたびに再評価/通知するように設定されています。書き込み可能なdependentObservableでは、書き込み関数は実際には書き込みをインターセプトする場所であり、読み取り関数が適切な値を返すように、必要なオブザーバブルを設定できます(書き込みは通常、読み取りの逆です。値を変換しています)。

あなたの場合、私は個人的にオブザーバブルを使用して値を表し、次にそのオブザーバブルへの手動サブスクリプションを使用して元の値(あなたが制御できない可能性があるもの)を更新します。

次のようになります:http://jsfiddle.net/rniemeyer/Nn5TH/

したがって、このフィドルは解決策になるようです

var viewModel = {};

// simulating a cookie store, this part isnt as important
var cookie = function () {  

    // simulating a value stored in cookies
    var privateZipcode = "12345";

    return {
        'write' : function (val) { 
            console.log("updated cookie value with: " + val);
            privateZipcode = val; 
        }, 
        'read': function () { 
            return privateZipcode; 
        }
    }
}();

viewModel.zipcode = ko.observable(cookie.read());

// manually update the cookie when the observable changes
viewModel.zipcode.subscribe(function(newValue) {
   cookie.write(newValue);   
});

ko.applyBindings(viewModel);​

それは理にかなっており、使用するのはやや簡単です。全体として、サーバーがajaxリクエストなどでCookieを編集できるため、Cookieを監視可能なものとして扱うことがどれほど優れているかはわかりません。

于 2012-03-22T00:17:03.187 に答える
0

内部のprivatezipcodeを監視可能にしてみてください。ここを参照してください:http://jsfiddle.net/KodeKreachor/fAGes/9/

于 2012-03-21T23:42:42.737 に答える