這是一個棘手的問題 - 當你想在ASP.NET Web窗體中使用動態控件時,你必須選擇兩個惡意中較小的一個。最終,這歸結於您想要達成的妥協方案:演示者在視圖中擔憂或擔心演示者的擔憂。
當我在網頁表單的工作,我通常更喜歡後者 - 我接受了主持人是聯繫在一起的ASP.NET頁面的生命週期,並創建一個InitializeView
方法做任何有必要創建動態控件:
// Presenter
// This could also be parameterless if you prefer that idiom but
// then the view needs a SelectedState property that serves up values
// straight from the Form collection, and it won't be obvious why.
public void InitializeView(string selectedState) {
if (selectedState != null) {
view.Counties = dataLayer.GetCounties(selectedState);
}
}
// View
protected void Page_Init(object sender, EventArgs args) {
presenter.InitializeView(Request.Form["StateList"]);
// ... build counties drop-down ...
}
當然,這會將演示者的語義與ASP.NET生命週期聯繫起來,並遮蔽了該方法中正在發生的事情。您可以通過給予InitializeView
一個更具描述性的名稱(如ProcessSelectedState
)來緩解這種情況,但除非方法名稱引用頁面生命週期,否則它永遠不會很明顯,爲什麼您不只是讓其他模型的縣(在presenter.LoadModel
或其他你可以稱它)。
我可以看到替代是如何吸引人:
protected void Page_Init(object sender, EventArgs args) {
if (Request.Form["StateList"] != null) {
List<string> counties = presenter.GetCounties(Request.Form["StateList"]);
// ... build counties drop-down ...
}
}
的Presenter
的語義是非常明確 - 這是很容易理解什麼GetCounties
不和它沒有任何與頁面生命週期。但是在你看來,你有可測試的東西,這是一件令人失望的事情,而這通常比讓我的演示者不理解他們的視圖引擎更重要。
另一種替代方法是在頁面初始化期間只加載您的整個模型。您的服務器控制值將不可用,因此您必須從Request.Form
中獲取任何這些值。這雖然不是慣用的ASP.NET經典 - 但它可能會讓人過度困惑,因爲大多數Web表單開發人員習慣於直接從Web控件獲取值,而不是直接從POST數據獲取值。
我還不清楚爲什麼主持人需要知道頁面的生命週期。主持人是不是僅僅爲視圖提供一個集合?服務器控件是不是在視圖中創建和渲染的? – BlackICE 2010-04-05 14:38:25