1

2 つの異なる AJAX 呼び出しを使用して、現在の値と利用可能なオプションの両方を取得する必要があります<select />(いくつかの理由でそれらをキュー/チェーンすることはできません)。

それが問題かどうかはわかりませんが、現在の値を読み取る呼び出しは、使用可能なオプションを毎回読み取る呼び出しの前に完了します。

Knockout 2.0.0 と Knockout Mapping 2.0.3 を使用して select を でバインドしdata-bind="options: values, value: valueComputed"ましたが、利用可能なオプションを取得する呼び出しが完了するまで、Knockout が最初の AJAX 呼び出しによって設定された値を削除/無視していることがわかりました。現在の価値。

これは正しいです?ノックアウトに「これが現在の値です。利用可能なオプションが利用可能になったら、それを選択してください」と伝えることはできますか?

いくつかのテストの後、私はクラッジを思いつきました.selectの値にプレーンなオブザーバブルをバインドする代わりに、値をインターセプトし、新しい値が未定義の場合は基になるオブザーバブルを変更しない計算されたオブザーバブルを使用しました。

私は何か悪いことをしていますか?

jsFiddle の例: http://jsfiddle.net/KeNUU/

私が使用している JavaScript コード:

var viewModel = function () {
    var self = this;

    // The underlying observable where
    // the selected value is stored.
    self.value = ko.observable();

    // The observable bound to
    // the value of the drop down.
    self.values = ko.mapping.fromJS([]);

    // Use a computed observable to intercept the undefined
    // value placed by KnockOut when binding the drop down.
    self.valueComputed = ko.computed({
        "read": function () {
            return ko.utils.unwrapObservable(self.value);
        },
        "write": function (value) {
            // Update the underlying observable only when
            // there is a value, if it's undefined ignore it.
            if (value) {
                self.value(value);
            }
        }
    });

    // Simulate the AJAX request which fetches the actual value,
    // this request must complete before the second one.
    setTimeout(function () {
        self.valueComputed("b");
    }, 1000 * 1);

    // Simulate the AJAX request which fetches the available values,
    // this reqest must complete after the first one.
    setTimeout(function () {
        ko.mapping.fromJS(["a", "b", "c", "d"], {}, self.values);
    }, 1000 * 2);
};

$(document).ready(function () {
    ko.applyBindings(new viewModel());
});
4

1 に答える 1

2

あなたがしていることで問題が発生するとは思いませんが、KO のロジックを回避して、価値にバインドされているものがオプションの有効な選択であることを確認しています。さらに、optionsCaption空白の選択肢を提供するために を使用していた場合、値を消去することはできません。あなたの場合、それは問題にならないでしょう。

より簡単な選択は、初期値を非観測可能オブジェクトにキャッシュし、それを使用しvalueてリストが戻ってきたときに入力することだと思います。リストが最初に来た場合、初期値はなく、通常どおりに機能します。

何かのようなもの:

setTimeout(function () {
    self.initialValue = "b";
    self.value("b");
}, 1000 * 1);

// Simulate the AJAX request which fetches the available values,
// this reqest must complete after the first one.
setTimeout(function () {
    ko.mapping.fromJS(["a", "b", "c", "d"], {}, self.values);
    if (self.initialValue) {
         self.value(self.initialValue);
         self.initialValue = null;
    }    
}, 1000 * 2);

http://jsfiddle.net/rniemeyer/gB3E5/

これで、ドロップダウンへの変更ごとに計算された観察可能なインターセプトを持つという (マイナーな) オーバーヘッドなしで、これを事前に処理できます。

于 2012-03-05T18:25:44.527 に答える