【问题标题】:ASP.Net MVC: Creating custom controls kind of messy?ASP.Net MVC:创建自定义控件有点乱?
【发布时间】:2010-11-02 12:56:31
【问题描述】:

主要问题:有没有更好的方法来完成创建可重用控件?

所以我们的想法是制作一个分页控件,基本上不再需要在多个视图上输入几乎相同的标记。它是这样的:

 <%= Html.ActionLink("First", "Details", new RouteValueDictionary(new { parentForumId = Model.TopicId, pageNumber = Model.FirstPage, amountToShow = Model.AmountToShow }))%>
 | 
 <%= Html.ActionLink("Previous", "Details", new RouteValueDictionary(new { parentForumId = Model.TopicId, pageNumber = Model.PreviousPage, amountToShow = Model.AmountToShow }))%>
 |
 <%= Html.ActionLink("Next", "Details", new RouteValueDictionary(new { parentForumId = Model.TopicId, pageNumber = Model.NextPage, amountToShow = Model.AmountToShow }))%>
 |
 <%= Html.ActionLink("Last", "Details", new RouteValueDictionary(new { parentForumId = Model.TopicId, pageNumber = Model.LastPage, amountToShow = Model.AmountToShow }))%>

然后把它变成这样:

<%= Html.Pager("View", "Controller", "RouteName", Model, new Dictionary<String, Object> { {"parentForumId", Model.ParentForumId}}, " ") %>

如您所见,我传入了所需的视图、控制器、路由名称、模型和字典,用于将请求变量添加到链接的 url。

我发现我必须为 HtmlHelper 类创建一个扩展方法,并且基本上将 ASP.Net 中的完整类(使用 CreateChildControls 之类的好方法)并将其全部塞入一个返回字符串。

这是执行此操作的首选方式吗? ASP.Net 方式的一个好处是标记到类,因为您拥有将标记属性转换为类属性的 html 标记标记。它通常用于更清晰的标记,但不可否认的是“假”html。在这种情况下,我有一个方法可以用一英里长的签名抽出 html。而且由于我没有基本的 WebControl 类,所以我制作的每个控件都必须具有具有相同基本需求的方法调用,例如 CssClass 或 ID。

话虽如此,我想我可以传入一个属性字典,因为 HtmlHelper.GenerateRouteLink 无论如何,我正在使用的方法调用一个,但这看起来真的很乱。

有没有更好的方法来做到这一点?

【问题讨论】:

    标签: asp.net-mvc controls


    【解决方案1】:

    首先,它都是 ASP.NET...一个是 MVC,另一个是 WebForms。当你一直说“ASP.NET 方式”时,我花了一秒钟才意识到你在说什么。 :P

    使用 MVC 的想法是,您的视图是“愚蠢的”,除了渲染数据的绝对基础基础之外没有任何实际行为。在 WebForms 中,视图与呈现它们和处理视图事件的行为紧密相关。这虽然很方便,但使 WebForms 视图很难进行单元测试,因为视图内容和行为是链接的,有时是混合的。

    MVC 视图使用 HtmlHelper 和 AjaxHelper 之类的东西的原因是为了尽可能将行为与视图分开。与 WebForms 中的用户或服务器控件不同,您可以对 Html.Pager 扩展方法进行完全单元测试,因为逻辑是纯代码,无需混合这些 UI 关注点或链接到一堆不可测试的 UI 级别类型。同样的一般规则适用于 MVC 控制器……它们只是代码,没有链接到事件或类似的东西。

    短期内可能不太方便,因为您目前已经习惯了旧的 WebForms 做事方式。不过,给自己一些时间,您可能会开始意识到 MVC 的首选做事方式带来的好处。在 HtmlHelper 上编写 Pager 扩展方法确实是使用 MVC 做事的首选方式。

    至于一英里长的签名位...搜索(尝试 Bing.com!)以获取流畅的样式界面和 HtmlHelper。 Fluent 风格开始在 MVC 视图等环境中占据重要地位,在这些环境中您可能拥有大量签名。总体思路是基于方法链,有点像 jQuery,并且可以将这些长签名缩短为一系列更短且更有意义的链式方法调用,这些方法调用设置您的 html 帮助器,最后调用 .Render 方法或其他东西相似的。

    【讨论】:

      【解决方案2】:

      你可以把它放在局部视图中,而不是创建一个助手。

      【讨论】:

        【解决方案3】:

        您可能想查看Martijn Boland's Pager control 以获得一些灵感。

        就我个人而言,对于我的可重用网格控件,我使用了一个类,该类包含生成具有分页、排序等功能的网格所需的所有信息......我调用局部视图来生成单独的元素(分页器、列选择、页面大小选择、 ...),将他们需要的信息传递给他们。

        这样我可以很容易地用自定义的东西扩展网格。例如,我可以创建一个 Mygrid_editableTable.ascx 视图来显示文本框而不仅仅是文本,并添加一个带有提交按钮的额外列。这样一边继续使用分页,一边选页,...

        【讨论】:

        • 是的,这就是我所做的(Noland 的寻呼机),因为我有一个模型基类,其中包含诸如下一页号和最后一页号之类的内容。视图本身是使用该模型类“键入”的。
        • 将按照 Robert Harvey 和您的建议调查部分观点。
        【解决方案4】:

        我们最终为分页器使用了 html 助手,因为它们很容易进行单元测试。分页业务需求可能很挑剔。

        “将少于 35 个链接显示为数字,然后按 20 分组,除非有超过 100 页的结果,在这种情况下按 100 分组……但在星期四,或对 GoogleBot,将它们显示为……等等。”

        此外,我们的 SEO 人员不断改变他们对哪种形状的网址获得最多汁液的想法。在这种情况下,必须进行单元测试!

        【讨论】:

        • 幸运的是,现在它只是一个简单的第一、上一个、下一个、最后一件事,所有这些都在控制器上完成,并且页码值通过模型发送。不过我明白你的意思。
        猜你喜欢
        • 1970-01-01
        • 2011-12-20
        • 2016-06-19
        • 1970-01-01
        • 2016-10-06
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多