2011-08-08 61 views
4

我是從WPF(MVVM)背景並嘗試轉移到MVC 2.是否有MVC2中的任何模式,您可以使用您用來提交的命令/命令按鈕(如<input>)該窗體使您可以在嘗試渲染視圖時隱藏/禁用該窗體。ASP MVC 2用於實現CanExecute樣式命令的模式

在MVVM世界中,您的命令可以實現ICommand接口,並且它有CanExecute方法,這非常有用。我想知道在ASP MVC 2中是否有類似的東西?

我能想到的唯一方法就是在View中執行此操作,以便我可以檢查ViewModel(CanSave)上的標誌並根據顯示/隱藏<input>標籤。

基本上我想有2個版本的網站正在運行,一個處於只讀模式和另一個編輯模式。

讓我知道你是否需要任何澄清。

回答

2

ASP .NET MVC沒有提供'controls'的概念,就像傳統的ASP.NET和WPF一樣。 ASP.NET MVC的基礎塊是HTML元素,如<input>,<button>等等。當然,這些不提供您正在尋找的功能(即實現ICommand接口)。

您正在查看的場景(即表單的兩種模式)可以(並且可以說是應該是)在查看級別處理。您已經面對正確的方向:在模型上有一個'CanSave'屬性,並在視圖中使用它來確定生成的內容。

例子:

<% if (Model.CanSave) 
    { %> 
     <p>First Name: <%= Html.TextBox("firstname", Model.firstname) %> </p> 
<% } 
    else 
    { %> 
     <p>First Name: <%=Model.firstname %></p> 
<% } %> 

你可能想簽出DisplayTemplatesEditorTemplates ...對於這種情況非常方便。布拉德威爾遜做得很好here

它會幫助你移動到這個:

<%= (Model.CanSave) ? Html.EditorFor(x => x.firstname) : Html.DisplayFor(x => x.firstname) %> 

...,讓您的瀏覽乾淨,漂亮。

+0

tnx。那就是我想要去的那個指導 –

0

我發現的一種方法是使用Filter屬性,您可以將它放在Actions中,但只能在服務器端處理CanExecute。

對於GUI的一面,不可能找到更好的辦法不是把如果檢查語句,如果用戶具有特權運行特定動作(即編輯/刪除按鈕)

1

如果你不能得到MVC做到這一點它的手工編碼這種vb樣式的僞代碼相對值得。這涉及到...

子類化您的控件。

並不像聽起來那麼痛苦,但它是一箇中等大小的人。因此它只適用於中型到大型應用程序。但值得他們。

Interface BaseUIControl 
    Property Enabled as Boolean 
    Property Visible as Boolean 
    Property Name as String 
    Property EntireStateAsXML as string ' You can use this to do EVERYTHING!   

Interface UserActionItem 
    Event Clicked(sender as UserActionItem ... don't pass anything from UI namespaces!) 

Class MyButton (or link, etc.) Implement BaseUIControl, UserActionItem Inherits UI.Button 

這有什麼用?你基本上已經替換了缺失的功能。您的控制器(甚至應用程序層)只能通過接口瞭解UI組件,因此它們不必查看UI類型。

更多...

您可以利用這一理念來控制一切。這爲我節省了數千小時的猴子代碼。

Interface TextControl 
    Property Value as text 

Interface CheckControl 
    Property Checked as boolean 

上面兩個是很基本的 - 你從UI版本繼承MyCheckBox和MyTextBox,並實現相應的。

當然,您可以設置通用代碼來循環所有控件並自動驗證(或循環並獲取每個人的XML以自動綁定整個表單)。

Interface ValidationBase 
    Property Required as Boolean 

如果你有一個文本或純數字掩蓋或建成2子restricitons ...

Interface ValidationNumeric   
    Property MinVal, MaxVal as double 

Interface ValidationText 
    Property MinLen, MaxLen as double 

不,它不會去到數據庫爲您服務。但是這在地毯下掃了一大堆。

你甚至可以在UI設計器中設置這些屬性值 - 是的,將BL放在牀上用戶界面,但是,如果你只有一個用戶界面,實際上工作得很好。

現在用圖像一樣的東西列表框/多選,雙擊列表選取器控件,檢查列表框,選項按鈕/複選框的組框的混合一個UI ...

Interface Selector 
    property Items as list (of string) 
    property SelectedItems as list (of string) 

使用的UI是什麼在起作用 - 你的通用例程可以不在乎他們看起來像什麼!子類的UI片斷將實現它們來設置/獲取正確的值。此外,我們添加了'validationEquation',ActivatesEquation(gray/ungray),SetValueTriggerEquation(如果爲true,將值設置爲SetValueEquation,否則,單獨保留),允許將控件設置爲來自其他項目的簡單值(基本上就像使用反射從綁定對象中獲取值一樣)通過Pascal Gayane的Expression Evaluator(它讀取.net類型!)

您也可以子類化主表單,讓它通過它的所有子控制進行遞歸,將XML的整個屏幕,並像這樣序列化。您可以讓自己的類在非UI圖層中實現這些類,並使用它們完全(de /)序列化UI狀態,並使用它們讀取UI(如果它們與業務對象相關)以映射到它。

這是令人難以置信的這是多麼簡化一個複雜的應用程序。我們有一個擁有1200多個數據輸入面板的頁面(...頁面...我們是一個厚厚的應用程序),可以在250K LOC中填寫250種不同的紙張。表單定義包含每個控件的「名稱」,這是從屏幕生成的XML中提取的。我們可能節省了500K LOC,因爲許多屏幕沒有代碼,或者只有微不足道的代碼;所有的數據綁定,驗證等都由引用接口的常用例程處理。

就像我說的,這隻適用於一個大的應用程序。儘管花了至少2-3周的時間來開發90%的功能,在整個2年的時間裏大概還有一個月成熟。我猜你的應用程序很大,如果你關心ICommand及其便利性。我會把投資回報放在15-20頁中等複雜的頁面上。

1

如果我正確地理解了這個問題,你可以寫一個ControllerCommand類來封裝它。事情是這樣的:

public class ControllerCommand 
{ 
    public string Action { get; set; } 
    public string Controller { get; set; } 
    public object RouteValues { get; set; } 
    public bool IsEnabled { get; set; } 
} 

您的詳細視圖模型可能會使用這樣的:

public class DetailsModel 
{ 
    public guid Id { get; set;} 
    // some other viewmodel properties 
    public ControllerCommand Edit { get; set; } 
} 

你可以在HtmlHelper編寫擴展方法來取代內置的:

public MvcHtmlString CommandLink(this HtmlHelper html, string linkText, ControllerCommand command, object htmlAttributes) 
{ 
    if (command.IsEnabled) 
    { 
     return html.ActionLink(linkText, command.Action, command.Controller, command.RouteValues, htmlAttributes); 
    } 
    else 
    { 
     return MvcHtmlString.Create(linkText); 
     // perhaps return <span class="disabled-command">linkText</span> 
    } 
}