2011-06-29 52 views
10

我對MVVM相當陌生,所以請原諒,如果這個問題有一個衆所周知的解決方案。MVVM模型中的非阻塞延遲加載屬性

我們正在構建一堆模型類,它們具有一些預先加載的核心屬性,以及一些附加屬性,這些屬性可以通過進行Web API調用按需加載(update:澄清,這將是每個懶惰加載的屬性的Web API調用)。

而不是有多個模型,有一個單一的模型與延遲加載邏輯在那裏似乎是明智的。但是,似乎延遲加載的屬性在訪問時不應該被阻塞,所以當View綁定到ViewModel並且綁定到Model時,我們不會阻塞UI線程。因此,我正在考慮一種模式,當模型的惰性屬性被訪問時,它開始異步獲取,然後立即返回默認值(例如null)。當異步提取完成時,它將引發一個PropertyChanged事件,以便ViewModel/View可以重新綁定到獲取的值。

我已經試過了這一點,它似乎相當不錯的工作,但不知道:

  1. 是否有任何陷阱,以這種方法,我還沒有發現關於尚,但會碰上如該應用的複雜性增加了嗎?
  2. 這個問題是否存在解決方案,這個解決方案既可以嵌入到框架中,也可以廣泛用作第三方框架的一部分?
+0

我可以想到的一個可能的問題是,您需要監聽所有這些懶惰加載器上的PropertyChanged事件,這意味着如果您有一個依賴這些加載器的多個屬性或函數,它將不得不在執行自己的代碼之前等待它所依賴的所有加載器完成。 這可能導致必須編寫大量的邏輯,否則這些邏輯可能會被編寫爲一個單獨的線程調用,該調用結合了在單獨的線程中「同步」提取延遲加載器。 –

+0

@蒂莫西 - 好點。我已經考慮過了,我的感覺是,由於延遲加載數據的性質,任何事情都不可能依賴於多個懶惰數據。很可能多件事情依賴於單一的懶惰數據,但我認爲這不是一個問題。 –

+0

我使用上面描述的確切方法,它工作得很好。 – Jeff

回答

6

我在過去做過這樣的事情,而我一直遺忘的一件事是您無法通過任何類型的代碼調用您的異步屬性,並期望它具有值。

因此,如果我延遲加載Customer.Products的列表,我不能在代碼隱藏中引用Customer.Products.Count,因爲第一次將其稱爲值爲NULL或0(具體取決於是否創建空白集合)

除此之外,它對綁定非常有用。我使用Async CTP庫進行異步調用,我發現這對於這樣的事情來說絕對是美妙的。

public ObservableCollection<Products> Products 
{ 
    get 
    { 
     if (_products == null) 
      LoadProductsAsync(); 

     return _products; 
    } 
    set { ... } 
} 

private async void LoadProductsAsync() 
{ 
    Products = await DAL.LoadProducts(CustomerId); 
} 

更新

我記得還有一件事我有問題與是,實際上是NULL數據。如果Customer.Products實際上從服務器返回NULL值,我需要知道async方法已正確運行,並且實際值爲null,因此它不會重新運行async方法。

如果有人在第一次異步調用完成之前第二次調用Get方法,我也不希望異步方法運行兩次。

我在當時解決了這個問題,因爲每個異步屬性都有一個Is[AsyncPropertyName]Loading/ed屬性,並在第一次異步調用期間將其設置爲true,但我並不是很高興需要爲所有異步屬性創建額外屬性。

+0

*(增加了語法高亮)* –