-2

2 つの選択コントロールがあり、選択時に両方の選択コントロールに新しいデータを再入力したいと考えています。たとえば、1 つのオプションを選択すると、関連するサブスクライブ関数が呼び出され、新しいデータが「更新」関数に渡され、ここで新しいデータが両方の選択コントロールに設定されますが、この時点で再帰の問題が発生します。サブスクライブ関数を再度呼び出すなどなので、基本的に、この再帰呼び出しを修正する方法がわかりません。

jsFiddle の例:

http://jsfiddle.net/fWTpE/

HTML :

<select class="select"  data-bind="value: currentSourceOne, options: sourceOne, optionsValue: function(item) { return item; }, optionsText: function(item) { return item.text; }, optionsCaption: &#39;Select&#39;"></select>

<select class="select"  data-bind="value: currentSourceTwo, options: sourceTwo, optionsValue: function(item) { return item; }, optionsText: function(item) { return item.text; }, optionsCaption: &#39;Select&#39;"></select>

JS :

function ViewModel(data) {

            var self = this;

            self.refresh = function (data) {

                if (data.currentObject != null) {

                    self.sourceOne(data.currentObject.sourceOne);
                }
            };

            self.currentObject = ko.observable(data.currentObject);

            self.sourceOne = ko.observableArray(self.currentObject().sourceOne);
            self.currentSourceOne.subscribe(function(value) {

                if(value) {

                    // omitted the code which generates new data

                    self.refresh(data);
                }
            });

            // omitted repetitive code for second select control
        };

        $(function () {

            // omitted the code which generates data

            ko.applyBindings(new ViewModel(data));
        });
4

1 に答える 1

0

マーク変数を追加して、再帰を中断できます。再帰が同期の場合、次のように実行できます。

function ViewModel(data) {
    var self = this;
    self.refresh = function (data) {
        if (data.currentObject != null) {
            self.sourceOne(data.currentObject.sourceOne);
        }
    };

    self.currentObject = ko.observable(data.currentObject);
    self.sourceOne = ko.observableArray(self.currentObject().sourceOne);
    // initialize a mark at outer scope
    var isSubscribing = false;
    self.currentSourceOne.subscribe(function (value) {
        // we are in a recursion, break out
        if (isSubscribing)
            return;
        // begin subscribing, set the mark
        isSubscribing = true;
        if (value) {
            // omitted the code which generates new data
            self.refresh(data);
        }
        // finished subscribing, restore mark
        isSubscribing = false;
    });
    // omitted repetitive code for second select control
};

$(function () {
    // omitted the code which generates data
    ko.applyBindings(new ViewModel(data));
});

ただし、subscribe-refresh-subscribe-... の再帰が非同期の場合は、 subscribe-refreshペアの実際の終了ポイントがどこにあるかを把握し、isSubscribing = false;そのポイントの最後に復元マーク コードを配置する必要があります。

于 2013-06-10T10:33:53.053 に答える