Ajax 仅在某些时候更新计算的可观测数据

Ajax 仅在某些时候更新计算的可观测数据,ajax,knockout.js,Ajax,Knockout.js,我有一个computed observable,它基于其他数据(在computed observable中)进行AJAX调用。结果数据用于填充部分UI。有时候UI的这一部分是隐藏的,我希望在隐藏时避免AJAX调用。现在我有以下内容,但只要isVisible变为true,它就会更新: this.loadData = ko.computed(function() { if (this.isVisible()) { this.isProcessing(true);

我有一个computed observable,它基于其他数据(在computed 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
为false时,不应进行任何更新。当
isVisible
为true时,只要
filteredSelectedDatasetLinks
发生更改,就会发生更新。当
isVisible
变为true时,如果
filteredSelectedDatasetLinks
在为false时发生更改,则会发生更新。

假设您希望在
filteredSelectedDatasetLinks
更改时调用ajax(并且仅在可见时?)。我认为最好的方法是使用
subscribe
函数使依赖关系显式化。。。(我稍微简化了一下,并解决了您最后一个“this”的问题)


您最初尝试的问题是ko.computed只运行一次函数,并自动计算出它需要订阅的观测值。在您的案例中,这包括
isVisible
observable(这不是您想要的)。但是,直接使用subscribe调用将其显式化,您不再需要担心
isVisible
触发回调。

以下是我根据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);

可能是在发出AJAX请求之前检查并在成功请求后清除的
filteredSelectedDatasetLinks
上的脏标志?脏标志是否可见?您将如何设置它--另一个计算的可观察订阅或手动订阅?如果唯一的依赖项是
filteredSelectedDatasetLinks
本身,那么我认为计算订阅或手动订阅是等效的。我会让它可见,但如果您已经在列出的计算中访问了
filteredSelectedDatasetLinks
,那么不管怎样它都会触发(不需要脏标志来触发任何东西,只需使用它来决定是否需要做更多的工作)我刚刚遇到了你的,这在概念上与我在这里所做的相似,并且在恢复计算时也会受到重新评估计算结果的副作用。这使我试图找出一个通用的可暂停计算,以满足我的条件。稍后我会发布更多。自从添加了节流功能后,我没有太多考虑可暂停的内容,但是尝试封装您所追求的内容的逻辑是一个有趣的想法。谢谢您的回答。但这并不能满足这个要求:“当isVisible变为true时,如果filteredSelectedDatasetLinks变为false,就会发生更新。”是的,这是有道理的。你的答案肯定是正确的。
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);