简体   繁体   English

ASP.NET MVC:“扩展” Html.TextBox有条件地具有CSS值?

[英]ASP.NET MVC: 'Extend' Html.TextBox to conditionally have CSS value?

I would like to extend ASP.NET MVC's TextBox so it conditionally switches its CSS value (based on data from the Model). 我想扩展ASP.NET MVC的TextBox,以便它有条件地切换其CSS值(基于来自Model的数据)。 However, I don't want to put that logic in my view (by conditionally changing htmlAttributes/via method call there), but instead extend the class so I don't clutter my view. 但是,我不想将这种逻辑放在我的视图中(通过在此处有条件地更改htmlAttributes / via方法调用),而是扩展该类,这样我就不会混乱我的视图。 Basically I want the TextBox on creation look at the Model to see if it has a dictionary entry with its own name, and then look up the associated CSS value if it finds it. 基本上,我希望创建时的TextBox查看Model,以查看其是否具有带有其自己名称的字典条目,然后在找到它时查找关联的CSS值。

The problems I encounter are: 我遇到的问题是:

1) How do I extend it? 1)如何扩展? The TextBox itself is already an extension method and not a class so I can't "inherit"? TextBox本身已经是扩展方法,而不是类,因此我不能“继承”吗?

2) How would I communicate the conditions affecting the TextBox's attributes from my controller method to the TextBox? 2)我该如何将影响TextBox属性的条件从我的控制器方法传达给TextBox?

Probably you should not couple your text box back to the model. 可能您不应该将文本框耦合回模型。 Always it's better idea to have dependencies just in one way. 总是以一种方式具有依赖关系总是更好的主意。 From model to view. 从模型到视图。

So indirect answer is to have yet another extension method that will accept enum or boolean and depending on this will add or not class name. 因此,间接的答案是拥有另一个扩展方法,该方法将接受enum或boolean,并根据此方法添加或不添加类名。

<%= Html.StyledTextBox("myField", ViewData["ShouldBeStyled"]) %>

Also there is direct answer. 也有直接的答案。

To extend ASP.NET MVC, you should write your own extension methods. 若要扩展ASP.NET MVC,应编写自己的扩展方法。 You can always call underline extension method. 您可以随时调用下划线扩展方法。 So your code could look like: 因此您的代码可能如下所示:

public static class MyCoolExtension
{
  public static string TextBox(this HtmlHelper htmlHelper, string name)
  {
     // get data from htmlHelper.ViewData and call another extension methods of the HtmlHelper 
    var className = htmlHelper.ViewData["someClass"];
    return htmlHelper.TextBox("myField", "30", new { @class = className });
  }
}

One thing you could do is to use ViewData to pass the desired CSS class to your view, then the view wouldn't need to be aware of your logic to do this. 您可以做的一件事是使用ViewData将所需的CSS类传递给视图,然后视图不需要知道执行此操作的逻辑。

To answer your specific questions, 要回答您的特定问题,

1: You are right, you cannot extend this, but here are two alternatives: one is to avoid the need for extending this at all, and making use of what is provided (such as using ViewData), and the other is to implement your own. 1:您是对的,您不能扩展它,但是这里有两种选择:一种是完全避免扩展它,并利用所提供的内容(例如使用ViewData),另一种是实现您的拥有。 You can download the MVC source code and work directly from there if you'd like. 您可以下载MVC源代码,并根据需要直接从那里工作。

2: Consider something in your controller: 2:考虑控制器中的某些内容:

if (someCondition)
{
    ViewData["someClass"] = "foo";
}
else
{
    ViewData["someClass"] = "snazzle";
}

and then in your view: 然后您认为:

<%= Html.TextBox("myField", "30", new { @class = ViewData["someClass"] }) %>

Best of luck! 祝你好运!
-f! -F!

Depending on how important it is to you, you could also use jQuery to apply formatting. 根据它对您的重要性,您还可以使用jQuery来应用格式。 It is very easy to select specific textboxes. 选择特定的文本框非常容易。

Is say "Depending on how important it is to you", because there is a group of users that have JavaScript disabled (that cannot be neglected), in which case the formatting won't be applied. 之所以说“取决于它对您的重要性”,是因为有一组禁用了JavaScript(不能忽略)的用户,在这种情况下,将不会应用格式。

This is why I'm so unhappy with the MVC team's decision to use strings everywhere. 这就是为什么我对MVC团队在任何地方使用字符串的决定感到不满意的原因。 Adding a class to a textbox should not be the concern of the TextBox HtmlHelper, it should be a separate aspect of building HTML. 将类添加到文本框应该不是TextBox HtmlHelper所关心的,它应该是构建HTML的一个独立方面。 Here is a better solution using a semantic model to define Html. 这是使用语义模型定义HTML的更好解决方案。 I'm going to use TagBuilder here, but I highly recommend looking into the HtmlTags library included with FubuMvc. 我将在这里使用TagBuilder,但我强烈建议您查看FubuMvc随附的HtmlTags库。

public TagBuilder TextBox(this HtmlHelper helper, string name, string value)
{
   var tag = new TagBuilder("input");
   tag.MergeAttribute("type", "text");
   tag.MergeAttribute("name", name);
   tag.MergeAttribute("value", value);
   return tag;
}

Now since we're returning a semantic (TagBuilder) model, we can continue to modify the model before converting it to an HTML literal. 现在,由于我们返回了语义(TagBuilder)模型,因此我们可以继续修改模型,然后再将其转换为HTML文字。 ConditionallyAddClass is a reusable extension method that will apply a class to any TagBuilder model: ConditionallyAddClass是可重用的扩展方法,它将对任何TagBuilder模型应用一个类:

public TagBuilder ConditionallyAddClass<T>(this TagBuilder tag, string @class, T model, Func<T, bool> condition)
{
   if(condition(model))
   {
      tag.AddCssClass(@class);
   }
   return tag;
}

In your view you can now do this (assuming StyleAgeTextbox is a boolean property): 在您的视图中,您现在可以执行此操作(假设StyleAgeTextbox是布尔属性):

<%= Html.TextBox("Age", Model.Age).ConditionallyAddClass("customClass", Model, m => m.StyleAgeTextbox) %>

The view engine would automatically call ToString() on the TagBuilder to get the proper HTML. 视图引擎将自动在TagBuilder上调用ToString()以获取正确的HTML。

I hope this gives you the basic idea. 我希望这给您基本的想法。 There are of course many ways you can extend this. 当然,有很多方法可以扩展此范围。 You could have a standard naming convention and use a dynamic type to get around using expressions or you could have lookup tables or strongly type the entire thing to use member expressions (eg TextBoxFor(m => m.Age)). 您可能具有标准的命名约定,并使用dynamic类型来使用表达式来解决问题,或者您可以具有查找表或强烈键入整个内容以使用成员表达式(例如TextBoxFor(m => m.Age))。 I prefer moving the entire thing into an html convention framework like Fubu does , but that's probably beyond most projects. 我更喜欢像Fubu 一样将整个内容移到html约定框架 ,但这可能超出了大多数项目。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM