-2

我有两个选择控件,在选择时我想用新数据重新填充两个选择控件。例如,如果我选择一个选项,它将调用相关的订阅函数,那么新数据将被传递给“刷新”函数,在这里它将新数据设置为两个选择控件,但此时我也遇到了递归问题,它再次调用订阅函数等等,所以基本上我不知道如何修复这个递归调用。

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 回答