Backbone - 防止在删除视图后延迟执行

Backbone - prevent deferred execution after view is removed

我有一个主视图,其中有一个框,您可以在其中切换子视图

获取 ajax 调用成功后,在主视图上显示 'success' div。

我面临的问题是,当我在子视图之间切换时,前一个视图的提取中的延迟承诺仍然会被执行并显示 'success' div.

这是我的代码:

this.model.fetch().done(function() {
  $('#success').show();
});

onChangeSubview: function() {
    this.subview.unbind();
    this.subview.remove();
}

这个 SO 问题 abort-ajax-requests-using-jquery 说你可以存储指向延迟的指针并通过调用 abort() 来停止它:

var fetchXhr = this.model.fetch().done(function() {
  $('#success').show();
});
onChangeSubview: function() {
    fetchXhr.abort();
}

我对每个子视图进行了几次提取,有些在一定时间间隔内重复,这意味着我必须存储每个提取请求并循环遍历它们并在每个子视图上调用中止。

是否有更好的方法来阻止延迟函数的执行? 例如:某种检查以查看子视图是否已被删除,或取消绑定所有延迟承诺的函数?

解决这个问题的一种方法是将子视图的所有提取添加到列表中,然后 onChangeSubview 遍历它们并执行中止,例如

this.fetches.forEach(function(fetchXhr) { 
    fetchXhr.abort(); 
}); 

或者如果你想使用下划线方式

_.invoke(this.fetches, 'abort');

您甚至可以将此功能放在您扩展的基础视图中,这样您就可以抽象出其中的一部分。

中止不一定是可取的,因为您可能希望视图即使在隐藏时也能继续刷新(承认您当前 unbind/remove)。

您当然可以通过采用导致“#success”元素有条件地显示的模式来避免中止的需要,例如,通过使用 returns 的方法装配 $('#success') 对象仅当特定子视图(或其容器)可见(或任何适合的标准)时才显示 #success 元素的函数。

// in some suitable outer context
var $success = $('#success');
$success.showConditional = function($container) {
    var $self = $(this);
    return function() {
        if($container.is(':visible')) {
            $self.show();
        }
    }
};

...

$subviewContainer = $("someSelector"); //or maybe the container is already a property of this or this.model?
this.model.fetch().done($success.showConditional($subviewContainer));

在所有提取都采用该模式后,#success 元素将不会显示隐藏或删除的子视图。

反正就是这个道理。您可能需要调整细节以适应您的整体模式。