2016-11-11 77 views
1

我有有有子視圖,你可以骨幹 - 防止視圖被刪除後

之間切換後取Ajax調用是成功的,一個「成功」格主視圖框主視圖延遲執行被顯示。

我面臨的問題是,當我在子視圖之間切換時,來自先前視圖的提取的延遲承諾仍然執行並顯示'成功'div。

這是我的代碼:

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

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

這太問題abort-ajax-requests-using-jquery說,你可以存儲的指針推遲,並通過調用中止(停止),像這樣:

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

我有幾個爲每個子視圖提取,有些在一個時間間隔內重複,這意味着我將不得不存儲每個提取請求,並通過它們循環,每次調用abort。

有沒有更好的方法來停止執行延期功能? 例如:某種檢查子查看是否已被刪除,或解除所有延期承諾的功能?

+1

只要大聲思考,你可以將所有提取的子視圖添加到列表中,然後onChangeSubview你可以遍歷它們並執行abort例如'this.fetches.forEach(function(fetchXhr){fetchXhr.abort();});'(或'_.invoke(this.fetches,'abort');'如果你想以Underscore的方式做到這一點)。你甚至可以把這個功能放到擴展的基本視圖中,這樣你就可以把它抽象出來。 – Dymos

+1

@Dymos +1。你太謙虛了,這不是一個評論,而是一個實際的答案;) – hashchange

+0

哈哈謝謝:-)我將它添加爲當時的後代的答案。 – Dymos

回答

1

中止不一定是可取的,因爲您可能希望即使隱藏視圖(承認您目前已取消綁定/刪除),仍可繼續刷新視圖。

可以可靠地避免需要通過採用使所述「#SUCCESS」元素的圖案來中止被有條件地示出,例如,通過操縱一個$('#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元素將不會顯示隱藏或移除子視圖。

無論如何這就是原則。您可能需要調整細節以適應您的整體模式。

+0

正在考慮同樣的事情,但並不確定如何測試移除的對象。你想檢查DOM的緩存的視圖jquery元素的回答,但我擔心這將是計算昂貴,所以我做了以下: 父視圖當前調用this.subviews.cleanup() ;當刪除子視圖。 我添加並設置一個字段「刪除」在子視圖的清理功能: 清理:function(){ this.removed = true; this.remove(); this.unbind(); } 而在ajax調用中,我做了檢查: this.model.fetch()。always(if(!! self.removed){return;} -code-); – Ta946

+1

看起來很酷。你可以通過從'.remove()'返回'true'來使'.cleanup()'在語法上更加整潔,從而允許你編寫'this.removed = this.remove()'。實際上,如果'this.remove()'有時可能失敗(即不移除),那麼這會很有用,在這種情況下(可能在try/catch的幫助下)它可能返回'false'。 –

1

解決此問題的一種方法是將所有的子視圖提取添加到列表中,然後onChangeSubview迭代它們並執行abort例如

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

,或者如果你想這樣做下劃線的方式

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

你可能甚至把這個功能在你你可以抽象一些穿幫所以擴展基本觀點。

+0

這是OP正在尋求的「更好的方式」,還是他已經知道的方式? –

+0

這是一種不同的方式:) - 它帶來的價值是在旁觀者的眼中 – Dymos