0

我有一个计算的 observable,它根据其他数据(在计算的 observable 中)进行 AJAX 调用。生成的数据用于填充 UI 的一部分。有时 UI 的那部分是隐藏的,我想在隐藏时避免 AJAX 调用。现在我有以下内容,但只要isVisible变为true

this.loadData = ko.computed(function() {
    if (this.isVisible()) {
        this.isProcessing(true);
        var self = this;
        $.when.apply($, ko.utils.arrayMap(this.parent.data.filteredSelectedDatasetLinks(), function(datasetLink) {
            return $.ajax({
                url: datasetLink.getDownloadUrl('.json'),
                success: function(data) {
                    //... do stuff with the data
                }
            });
        }))
        .done(function() {
            self.isProcessing(false);
        });
    }
}, this);

所以很明显我需要以某种方式把它分开,但我还没有想出如何去做。重申一下,当isVisible为假时,不应该发生更新。当isVisible为真时,只要filteredSelectedDatasetLinks发生变化就会发生更新。当isVisible变为 true 时,如果filteredSelectedDatasetLinks在它为 false 时发生更改,则会发生更新。

4

2 回答 2

0

大概你想在filteredSelectedDatasetLinks改变时调用你的ajax(并且只有在可见的情况下?)。我认为最好的方法是使用函数使依赖项显式subscribe化......(我已经稍微简化并修复了你最终的“this”的问题)

this.filteredSelectedDatasetLinks.subscribe(function() {
    if (this.isVisible()) {
        this.isProcessing(true);
        var self = this;
        $.when.apply($, ko.utils.arrayMap(this.filteredSelectedDatasetLinks(), function(datasetLink) {
            return $.ajax({
                url: datasetLink.getDownloadUrl('.json'),
                success: function(data) {
                    //... do stuff with the data
                }
            });
        }))
        .done(function() {
            self.isProcessing(false);
        });
    }
}, this);

您最初尝试的问题是 ko.computed 运行该函数一次并自动计算出它需要订阅哪些 observables。在您的情况下,这包括isVisible可观察的(这不是您想要的)。但是直接通过 subscribe 调用使其明确,您不再需要担心isVisible触发回调。

于 2013-02-15T23:48:56.797 回答
0

这是我根据 RP Niemeyer 的评论最终使用的内容。

this.trackData = ko.computed(function() {
    this.parent.data.filteredSelectedDatasetLinks();    // for notification
    this.isDataDirty(true);
}, this);

this.loadData = ko.computed(function() {
    if (this.isVisible() && this.isDataDirty()) {
        this.isDataDirty(false);
        this.isProcessing(true);
        var self = this;
        $.when.apply($, ko.utils.arrayMap(this.parent.data.filteredSelectedDatasetLinks.peek(), function(datasetLink) {
            return $.ajax({
                url: datasetLink.getDownloadUrl('.json'),
                success: function(data) {
                    //... do stuff with the data
                }
            });
        }))
        .done(function() {
            self.isProcessing(false);
        });
    }
}, this);
于 2013-02-16T00:03:29.303 回答