2011-08-08 25 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> 
    } 
}